Shell脚本深入教程:Bash变量
Bash变量
变量赋值
等号=
左右两边必须不能出现空白。当包含了特殊符号时,需要使用引号包围。使用单引号还是双引号,后面再详细解释。
1 | var1=22 # 数值 |
问题:var3=hello world
为什么报错的是没有world命令,而不是赋值错误?为什么echo = 3
不是赋值?
其实经常会看到这种用法,比如下面的命令模式,表示cmd命令执行时设置locale环境为C,但非cmd命令则不受影响:
1 | LC_ALL=C cmd |
使用unset
内置命令可以注销变量:
1 | var="hello world" |
使用readonly
内置命令可以定义只读变量,只读变量不可修改、不可注销。
1 | readonly xyz="helloworld" |
变量引用
使用$VAR
或${VAR}
,前者是简写,后者是规范引用。
例如:
1 | var='hello world' |
一定注意:变量的名称是var
,而不是$var
,$var
是在引用、访问变量在内存中保存的值。
使用${#VAR}
获取变量VAR保存的字符长度。
1 | a="hello world" |
当$VAR
引用方式会产生歧义时,就用${VAR}
,例如:
1 | VAR="hello" |
间接引用变量(动态变量)
假设有变量var=value
,当通过${!var}
语法来引用变量时,将表示先获取变量${var}
的值value
,再获取变量名为value
的值。这种语法称为变量的间接引用。
1 | value=hello |
有些时候需要获取动态变量的值(比如通过传参来获取指定参数对应的变量值),变量的间接引用将非常方便。
环境变量
在Shell脚本中偶尔会考虑用环境变量,但是环境的概念在Shell中很重要。
环境变量可以看作是一个全局变量,但这说法并不正确。后面我会详细解释何为Shell环境,这是Shell中非常重要的概念,到时候大家就会对环境变量有一个非常清晰的认识。
使用bash内置命令export
可以定义一个环境变量:
1 | 直接定义一个新的环境变量 |
环境变量一般以大写字母命名。
子Shell进程可以继承父Shell中的环境变量:
1 | x=1000 |
使用env
命令可以查看所有环境变量。
1 | env |
可以在某个命令行前设置变量,便表示设置该命令的专属环境变量,只有该命令进程中可访问该环境变量,其它任何地方都无法访问,且命令退出后专属环境变量消失。
1 | 下面等价 |
常见的环境变量:
1 | HOSTNAME=control_node |
特别要注意的是PATH环境变量,它决定了Shell调用命令时的搜索路径。经常会设置PATH环境变量,特别是应用在定时任务的Shell脚本。
1 | PATH=/usr/local/mysql/bin:$PATH |
比如,编译安装或直接解压安装程序时,通常会将PATH写入到/etc/profile.d/*.sh
下:
1 | echo 'PATH=/usr/local/mysql/bin:$PATH' >/etc/profile.d/mysql.sh |
位置参数和特殊变量
位置参数
Shell脚本运行时可能需要一些选项或参数。
比如,某脚本test.sh内容:
1 | !/bin/bash |
这表示先读取并输出第一个参数表示文件内容,然后touch第二个参数表示的文件。执行时:
1 | chmod +x test.sh |
脚本执行时的选项(本例没有选项)和参数都是脚本的位置参数,位置参数使用$1,$2,$3,...
引用。
$0
比较特殊,表示脚本名或当前Shell名称。
位置参数是相对于每个Shell进程而言的。对于Shell脚本来说,位置参数就是执行脚本时的参数部分。当处于Shell环境内时,也可以使用set --
设置当前Shell环境位置参数:
1 | set -- a b c |
特殊变量
Shell有一些特殊变量,这些变量由Shell自身动态维护,不允许用户手动修改。
为了让这些特殊变量更直观,我使用变量引用而不直接使用特殊变量名。
1 | $1,$2,...,$N:脚本的位置参数 |
关于$* "$*" $@ "$@"
的区别,参见如下shell脚本测试:
1 | !/bin/bash |
执行:
1 | chmod +x position_parameters.sh |
shift踢掉位置参数
Bash内置命令shift专门用来踢位置参数。在为Shell脚本设计选项、参数时,都会用到shift。
1 | shift [N] |
踢掉前N个位置参数,如果没有指定N参数,则默认N=1,即一次踢掉一个位置参数。
踢掉位置参数后,后面的位置参数会向前移动。
1 | set -- a b c d e f |
例如,自定义ping命令的选项、参数。
1 | !/bin/bash |