我们在bash中经常看到一些特殊的变量,我们罗列下
$0,$1,$$,$#,$@,$*,$?,$(),${},$(())和(())
接下来我们就来一一介绍下这些变量的意思
1.$0
$后面紧跟着数字,数字从0开始,0代表运行的脚本本身名称,1为第一个参数,2为第二个参数,依次类推
例如以下脚本,test.sh内容如下
#!/bin/bash echo $0 echo $1
我们运行
./test.sh sulao
打印出
./test.sh sulao
2.$#
传递给脚本或函数的参数个数,上述脚本添加一个
#!/bin/bash echo $0 echo $1 echo $#
然后比上面多打印一行2
3.$*
传递给脚本或函数的所有参数。
4.$@
传递给脚本或函数的所有参数。被双引号(" ")包含时,与 $* 稍有不同
参数被双引号包裹时$*会将参数作为一个整体输出,如果是$@还是作为N个参数输出
5.$?
上个命令的退出状态,或函数的返回值
6.$$
当前Shell进程ID,对于 Shell 脚本,就是这些脚本所在的进程ID
7.$()
$()和``用法差不多,都是用来做命令替换,将命令赋值给一个变量,但是$()这个不是每个bash版本都可以进行使用
8.${}
${a}和$a用法一样,只是可以更精确界定变量名称范围,例如
$ab 和 ${a}b
用了${}能够更方便的看清变量名
9.$(())
$(())是用来做整数运算的
在 bash 中,$(( )) 的整数运算符号大致有这些:
+ - * / :分别为 "加、减、乘、除"。 % :余数运算 & | ^ !:分别为 "AND、OR、XOR、NOT" 运算
10.(())
单纯用 (( )) 也可重定义变量值
a=5; ((a++)) 可将 $a 重定义为 6 a=5; ((a--)) 则为 a=4 a=5; b=7; ((a < b)) 会得到 0 (true) 的返回值。
常见的用于 (( )) 的测试符号有如下这些:
<:小于 >:大于 <=:小于或等于 >=:大于或等于 ==:等于 !=:不等于
扩展知识
$()和${}的其他用法
我们可以用 ${ } 分别替换获得不同的值:
我们定义一个变量
file=/dir1/dir2/dir3/my.file.txt
${file#*/}:拿掉第一条 / 及其左边的字符串:dir1/dir2/dir3/my.file.txt ${file##*/}:拿掉最后一条 / 及其左边的字符串:my.file.txt ${file#*.}:拿掉第一个 . 及其左边的字符串:file.txt ${file##*.}:拿掉最后一个 . 及其左边的字符串:txt ${file%/*}:拿掉最后条 / 及其右边的字符串:/dir1/dir2/dir3 ${file%%/*}:拿掉第一条 / 及其右边的字符串:(空值) ${file%.*}:拿掉最后一个 . 及其右边的字符串:/dir1/dir2/dir3/my.file ${file%%.*}:拿掉第一个 . 及其右边的字符串:/dir1/dir2/dir3/my
记忆的方法为:
# 是去掉左边(在鉴盘上 # 在 $ 之左边) % 是去掉右边(在鉴盘上 % 在 $ 之右边)
单一符号是最小匹配﹔两个符号是最大匹配。
${file:0:5}:提取最左边的 5 个字节:/dir1 ${file:5:5}:提取第 5 个字节右边的连续 5 个字节:/dir2
我们也可以对变量值里的字符串作替换:
${file/dir/path}:将第一个 dir 提换为 path:/ path1/dir2/dir3/my.file.txt ${file//dir/path}:将全部 dir 提换为 path:/ path1/path2/path3/my.file.txt
利用 ${ } 还可针对不同的变量状态赋值(没设定、空值、非空值):
${file-my.file.txt} :假如 $file 没有设定,则使用 my.file.txt 作传回值。(空值及非空值时不作处理) ${file:-my.file.txt} :假如 $file 没有设定或为空值,则使用my.file.txt 作传回值。 (非空值时不作处理) ${file+my.file.txt} :假如 $file 设为空值或非空值,均使用my.file.txt作传回值。(没设定时不作处理) ${file:+my.file.txt} :若 $file 为非空值,则使用 my.file.txt 作传回值。(没设定及空值时不作处理) ${file=my.file.txt} :若 $file 没设定,则使用 my.file.txt 作传回值,同时将 $file 赋值为 my.file.txt 。 (空值及非空值时不作处理) ${file:=my.file.txt} :若$file没设定或为空值,则使用my.file.txt作传回值,同时将 $file 赋值为my.file.txt 。(非空值时不作处理) ${file?my.file.txt} :若 $file 没设定,则将 my.file.txt 输出至STDERR。 (空值及非空值时不作处理) ${file:?my.file.txt} :若 $file 没设定或为空值,则将 my.file.txt 输出至 STDERR。 (非空值时不作处理)
以上的理解在于, 你一定要分清楚 unset 与 null 及 non-null 这三种赋值状态.
一般而言, : 与 null 有关, 若不带 : 的话, null 不受影响, 若带 : 则连null 也受影响.
还有哦,${#var} 可计算出变量值的长度:
${#file} 可得到 27
因为 /dir1/dir2/dir3/my.file.txt 刚好是 27 个字节...
另外还有一些变量赋值的一些技巧
${var} | 取变量原值,与$var一样 |
${var:=word} | 如果var为空或者未设定,返回word,且var=word |
${var:+word} | 如果var有值,返回word,var不变 |
${var:-word} | 如果var为空或者未设定,返回word,var不变 |
${var:?word} | 如果变量var为空或者未设定,返回word并退出shell,word没有值则输出:parameter null or not set,用于检测var是否被正常赋值 |
${var:num} | 返回var中第num个字符到末尾的所有字符,正从左往右,负从右往左,有空格:${var: -2},没有空格:${var:1-3}或${var:(-2)} |
${var:num1:num2} | 从var的第num1个位置开始,提取长度为num2的子串。num1是位置,num2是长度 |
${var/word1/word2} | 将var中第一个匹配到的word1替换为word2 |
${var//word1/word2} | 将var中所有word1替换为word2 |