Linux Bash Shell编程(四):变量(上) 变量分类与相关操作

Stella981
• 阅读 629

Linux Bash Shell编程(四):变量(上) 变量分类与相关操作

上一节,我们了解了Bash中的重定向以及特殊符号,从本节开始我们来一起探索Bash中变量的奥秘。本节我们先来了解下Bash中变量的基本知识以及对变量处理的操作方法。本节的部分内容(特殊符号等)在上一节中有叙述,不清楚的同学可以参阅上一节内容。

Linux Bash Shell编程(四):变量(上) 变量分类与相关操作

变量概述

  变量是计算机内存单元,其中存放的值可以变化,Shell脚本将信息存放在变量中,变量有一个名字,可以方便地引用,可以保存设置,也可以保存临时信息

Bash变量设置规则

  • Bash中的变量可以由字母、数字、下划线构成,但不能以数字开头
  • Bash变量的默认类型是字符串型,如果要进行数值运算,则必须指定变量类型为数值型或使用特殊运算方法
  • 在对变量赋值时,若变量值字符串中有空格,需要将整个值用引号包括,类同上一节
  • 使用echo命令输出变量值时,Shell同样对变量值进行当场转义,若在其中使用转义符\请使用-e参数激活转义
  • 环境变量名通常为大写,用户声明环境变量时也建议大写,以便于区分

变量分类

  • 用户自定义变量
  • 环境变量:主要保存和系统操作环境相关变量,环境变量不能改名,但能新建
  • 位置参数变量:主要用来向脚本中传递参数或数据,变量名不能自定义,变量作用是固定的
  • 预定义变量:是Bash中已经定义好的变量,变量名不能自定义,变量作用也固定(位置参数变量也是预定义变量的一种)

变量分类介绍与操作

  不同种类的变量操作大体相同,相同部分在用户自定义变量操作中写出,后面不再赘述

用户自定义变量

  • 用户自定义变量由用户自由定义修改,一般变量名可以修改,也可删除,在不违反Bash变量设置规则的前提下可以任意创建

  • 用户自定义变量仅在当前Shell中有效

  • 声明变量(定义变量), 语法:变量名=变量值 注意,等号两边均没有空格,否则会被Shell识别为命令而报错,例如

    test1="Hello" #定义了test1变量并赋值为"Hello"
    test2='Hello World!\nI am Zheng' #定义了test2变量并赋值为一个字符串,并含有转义符
    1test="Hello" #不能这样定义!!!变量不能以数字开头,见“变量设置规则”节
    

    注意,第三行声明的变量名称非法,变量名不能以数字开头第二行的变量值以’'单引号包含,因为其中有!特殊字符,若用双引号会报错,单引号消除!的特殊含义,详见上一节

  • 调用变量,语法:$变量名,例如,用echo命令将上面定义的两个变量输出

    zheng@Kali:~$ echo $test1
    Hello
    zheng@Kali:~$ echo $test2
    Hello World!\nI am Zheng
    zheng@Kali:~$ echo -e $test2 #test2变量值中包含转义符,需要用-e选项激活转义符
    Hello World!
    I am Zheng
    
  • 变量叠加:在变量后追加一部分内容而前面部分不变,用括号与引号包含原变量并在后面写入追加内容,注意括号与引号的位置不同

    #语法:追加内容以123为例 test="$test"123 test=${test}123 #示例:在变量test1上追加内容 zheng@Kali:$ test1="$test1"" World" #追加的内容含有空格,故用引号包含 zheng@Kali:$ echo $test1 Hello World

  • 另外,使用set命令可以查看当前定义的所有变量和函数(不只是用户自定义变量)

  • 删除变量:unset命令以删除变量

    #语法:unset 变量名    只需要变量名即可
    #示例,以删除test1为例:
    unset test1
    

环境变量

  • 一部分为系统环境变量,无法修改名称,只能修改值,作用固定,用户可以另行添加环境变量

  • 环境变量会在当前Shell和这个Shell的所有子Shell中生效(子Shell是由Shell创建的Shell,可通过命令pstree查看进程树以查看Shell关系)

  • 将环境变量写入配置文件,则在所有shell中都永久生效(不写入配置文件不能永久生效),环境变量配置文件在下一节讲到

  • 环境变量定义:语法 export 变量名=;将变量声明为环境变量 export 变量名

    export test="Hello" #新定义一个环境变量
    export test #将定义的test变量声明为环境变量
    
  • 查询环境变量:命令env查询当前的环境变量

  • 调用、删除同用户自定义变量。

  • 问题:子Shell能否unset父Shell声明的环境变量?

    可以,但只是删除子Shell环境中的环境变量,父Shell中依然存在

常用环境变量

  • $PATH 是系统查找命令的路径(变量只增加不能覆盖)。内容为以冒号分割的路径,Shell中的命令补全以及执行都按照PATH环境变量中所指定的目录寻找

  • $PS1 其实PS1变量是环境变量中的子分支,不能用env命令查看,只能用set,定义了当前命令提示符样式

转义符搭配

作用

\d

显示日期

\h

显示简写主机名

\t

显示24小时制时间"HH:MM:SS"

\T

显示12小时制时间"HH:MM:SS"

\A

显示24小时制时间"HH:MM"

\u

显示当前用户名

\w

显示当前所在工作目录的完整名称

\W

显示工作目录的最后一个目录

显示当前命令序号

$

命令提示符,root#;普通用户$

先查看一下当前的PS1变量值

zheng@Kali:~$ echo $PS1
\u@\h:\w$

可以按照喜好对自己的命令提示符显示格式进行修改,如增加时间等

位置参数变量

  • 位置参数变量是预定义变量中的一种,比较少所以单独讨论

  • 位置参数变量的变量名及作用是固定的,不能修改其变量名称,只能对其赋值(无需手动,只需要在命令行后按空格分开附加即可,同其他命令的参数)

  • 位置参数变量的分类及作用

位置参数变量

作用

$n

n为数字,$0代表脚本本身, 1 − 9 代 表 第 一 到 第 九 个 参 数 , 第 十 以 上 参 数 用 大 括 号 包 含 , 第 十 个 : 1-9代表第一到第九个参数,第十以上参数用大括号包含,第十个: 1−9代表第一到第九个参数,第十以上参数用大括号包含,第十个:{10}

$*

表示命令行中的所有参数,$*将所有参数看作一个整体

$@

也表示命令行中的所有参数,$@将每个参数区分对待

$#

表示命令行中所有参数的个数

  • 其中$*$#的作用乍一看相同,其实略有区分,相当于一个为总和,而一个为遍历集合,在下面的实验三中直观地展示了它们的具体区别

实验:

  • 实验一:简单位置参数变量传入实验

    #这是test1.sh脚本文件中的内容,有关脚本文件的创建和执行请移步我的另一篇博客 Bash Shell编程(一) #!/bin/bash

    #参数变量脚本测试程序

    echo $0 echo $1 echo $2 echo $#

执行test1.sh并附加如下参数

zheng@Kali:~/Shell$ ./test1.sh Hello "I am Zheng"
./test1.sh # $0 脚本本身
Hello  # $1 第一个参数
I am Zheng # $2 第二个参数(包含空格的字符串)
2 # $# 一共输入了两个参数
  • 实验二:使用参数进行简单的加法运算

    加法运算的内容暂时超纲,在下一节中会讲到

    #这是test2.sh脚本文件的内容 #!/bin/bash

    #加法运算的具体语法在后面讲到,必须用两个括号包含 sum=$(($1 + $2)) echo$sum

  具体输出内容就不在这里呈现,如果输入两个数字,则会返回两个数字的和

  • 实验三:展示参数#@#*的区别

    #这是test3.sh中的内容
    #/bin/bash
    
    #区分$*与$@
    #其中for为循环语句,在后面会讲到,与其他编程语言中的循环语句相同,类似 Python
    #本例仅作为了解两参数区别使用
    
    x=1
    echo '$*'
    for i in "$*"
      do
        echo "The parameter$x is $i"
        x=$(($x+1))
      done 
      
    x=1
    echo '$@'
    for i in "$@"
      do 
        echo "The parameter$x is $i"
        x=$(($x+1))
      done
    

    以如下参数执行test3.sh脚本,得到输出如下,

    zheng@Kali:~/Shell$ ./test3.sh 123 456 789
    $*
    The parameter1 is 123 456 789
    $@
    The parameter1 is 123
    The parameter2 is 456
    The parameter3 is 789
    

    可以清楚区分,$*表示的是参数总和,只有一个;而$@表示的是各个独立参数组成的集合,可以遍历

预定义变量

  • 预定义变量主要存放Shell执行状态相关的信息

    预定义变量

    变量作用

    $?

    最后一次执行的命令的返回状态,若正确运行则为0;错误退出,则由程序自己定义返回值(非0)

    $$

    当前进程的进程号(PID)

    $!

    最后一个被放入后台执行的进程号

    • 预定义变量中的$?变量就是上一节多命令顺序逻辑符号中&&逻辑与和||逻辑或中命令是否成功执行的判断依据
    • 在命令行后加&可以将命令放入后台执行,在后面会讲到

接收键盘输入给变量赋值

主要用read命令实现

read [选项] [变量名]

选项

作用

-p “string”

显示提示信息

-t time (second)

指定等待时间(默认永久) ,等待时间结束自动结束输入

-n 字符数

接收指定的字符数后,程序就执行

-s

隐藏输入的数据,适合机密信息的输入

例如:

#以下为test4.sh文件中内容
#!/bin/bash

#read接收键盘输入示例

read -p "Please input your name: " -t 60 name
echo "Hello, $name!"

运行以下命令,提示输入姓名,输入后回车得到输出

zheng@Kali:~/Shell$ ./test4.sh
Please input your name: Zheng
Hello, Zheng!

结尾

  下一节,我们将继续探索Bash变量相关内容,学习变量的数值运算与运算符、变量测试与内容替换、环境变量配置文件相关知识

输入示例

read -p "Please input your name: " -t 60 name
echo “Hello, $name!”

运行以下命令,提示输入姓名,输入后回车得到输出

```bash
zheng@Kali:~/Shell$ ./test4.sh
Please input your name: Zheng
Hello, Zheng!

结尾

  下一节,Linux Bash Shell编程(五):变量(下)变量运算、内容替换、环境变量配置文件
我们将继续探索Bash变量相关内容,学习变量的数值运算与运算符、变量测试与内容替换、环境变量配置文件相关知识

  上一节,Linux Bash Shell编程(三):重定向、多命令顺序、通配符、特殊符号

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Easter79 Easter79
2年前
swap空间的增减方法
(1)增大swap空间去激活swap交换区:swapoff v /dev/vg00/lvswap扩展交换lv:lvextend L 10G /dev/vg00/lvswap重新生成swap交换区:mkswap /dev/vg00/lvswap激活新生成的交换区:swapon v /dev/vg00/lvswap
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
待兔 待兔
2个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Wesley13 Wesley13
2年前
Java获得今日零时零分零秒的时间(Date型)
publicDatezeroTime()throwsParseException{    DatetimenewDate();    SimpleDateFormatsimpnewSimpleDateFormat("yyyyMMdd00:00:00");    SimpleDateFormatsimp2newS
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
8个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这