本文转载自微信公众号《Linux开发那些事》,作者LinuxThings。转载此文请联系Linux开发那些事公众号.在Bash解释器中,有许多内置变量。这些变量的功能是解释器自带的。如果我们在编写shell脚本的时候能够灵活的使用它们,对于脚本的编写效率和出错率都会有很大的帮助。下面一一介绍这些变量$FUNCNAME、$LINENO、$PWDFUNCNAME和LINENO经常用于调试脚本。FUNCNAME表示当前函数的名称,其范围仅限于在函数中使用。它在函数之外没有任何价值。LINENO表示变量出现在当前脚本中的行。数字PWD表示当前目录,对应pwd命令,已有一个脚本a.sh,内容如下:1#!/bin/bash234testa()5{6echo'func='$FUNCNAME,$LINENO7}8910testa1112echo'lineno:'$LINENO13echo'xx:'$FUNCNAME14echo'curpath:'$PWD执行./a.sh命令,输出如下[tt@ecs-centos-7~]$./a.shfunc=testa,6lineno:12xx:curpath:/home/ttintesta函数中FUNCNAME变量的值为testa,即函数名。它在函数之外没有任何价值。LINENO变量表示当前行号,无论是在函数内还是函数外。$$和$PPID这两个变量依次表示当前进程。ID和父进程ID的现有a.sh脚本,内容如下sleep20sleep语句是暂停脚本执行进程退出,在另一个终端验证输出结果#!/bin/bash#set-uecho'curpid:'$$echo'parentpid:'$PPIDsleep20在当前终端执行./a.sh,结果如下[tt@ecs-centos-7~]$./a.shcurpid:13095parentpid:12982退出执行a.sh的脚本进程之前,另开一个终端,执行ps-opid,ppid,time,cmd-p12982,13095命令,结果如下[tt@ecs-centos-7~]$ps-opid,ppid,time,cmd-p12982,13095PIDPPIDTIMECMD129821298100:00:00-bash130951298200:00:00/bin/bash./a.sh从上面的结果可以看出,执行./a.sh命令后$$变量代表执行a.sh脚本的进程ID13095,12982是其父进程ID,即PPID变量的值,即当前bash实例$0,$1,$2...$n,$#$#表示从命令行传递给脚本的参数个数$0,$1,$2...$n是从命令行传递给脚本的参数$0是参数的名字脚本本身$1是第一个参数$2是第二个参数,以此类推$n是第n个参数第十个参数及后面的参数必须用花括号括起来,例如:${10},${11},${12}代表第10个变量,第11个变量,第12个变量$*和$@都代表位置参数,但是它们之间有一些区别。使用$*时,如果加双引号,即"$*"形式,所有位置的参数都会被当作一个词,如果不加双引号,即$*形式,每个位置的参数将被视为一个独立的词。对于$@,无论是否加双引号,每个位置的参数都作为一个独立的词来处理已有的c.sh,内容如下#!/bin/bashcnt=1echo'test1111'forvarin"$*"doecho"arg$cnt="$varlet"cnt+=1"doneechocnt=1echo'test2222'forvarin$*doecho"arg$cnt="$varlet"cnt+=1"doneechocnt=1echo'test3333'forvarin"$@"doecho"arg$cnt="$varlet"cnt+=1"doneechocnt=1echo"test4444"forvarin$@doecho"arg$cnt="$varlet"cnt+=1"done执行./c.sh123,结果如下[root@ecs-centos-7~]#./c.sh123test1111arg1=123test2222arg1=1arg2=2arg3=3test3333arg1=1arg2=2arg3=3test4444arg1=1arg2=2arg3=3从上面的结果可以看出,对于$*,所有的位置参数加上双引号后都会被认为是一个词。对于$@,无论是否加双引号,结果都是一样的。那么,只有使用双引号时,$*和$@$才会有区别吗?命令、函数或脚本的退出状态对于判断命令的执行结果或函数的调用结果非常有用。现有的e.sh和f。sh测试脚本e.sh脚本#!/bin/bashtest_func(){if[[$1-eq10]];thenreturn5fireturn6}if[$#-ge1];thenname="$1"shift1$name"$@"fif.sh脚本#!/bin/bashshe.shtest_func3echo'exitcode1:'$?she.shtest_func10echo'exitcode2:'$?test-f$PWD/xx.txtecho'exitcode3:'$?test-f$PWD/e.shecho'exitcode4:'$?执行./f.sh命令,结果如下[root@ecs-centos-7~]#./f.shexitcode1:6exitcode2:5exitcode3:1exitcode4:0脚本e.sh中的test_func函数函数为:当该参数等于10时,退出状态为5,否则为6。she.shtest_func3命令会调用e.sh脚本中的test_func函数,传入参数为3,所以退出status为6。同理,she.shtest_func10命令的退出状态为5。在linux中,如果命令执行成功,则退出状态为0,失败则不为0。测试-f$PWD/xx.txt命令是检查当前目录是否存在。xx.txt存在,所以命令执行失败,退出状态为非0由于当前目录下存在e.sh,test-f$PWD/e.sh命令执行成功,退出状态为0$IFS该变量用于Bash识别字符串或单词边界。默认值是一个空格。可以根据需要在脚本中修改此变量的值。现有的b.sh脚本如下#!/bin/bashva="a:b:c"vb="x-y-z"vc="e,f,g"IFS=":"echo'va:'$vaecho'vb:'$vbecho'vc:'$vcechoIFS="-"echo'va:'$vaecho'vb:'$vbecho'vc:'$vcechoIFS=","echo'va:'$vaecho'vb:'$vbecho'vc:'$vc执行./b.sh结果如下[tt@ecs-centos-7~]$./b.shva:abcvb:x-y-zvc:e,f,gva:a:b:cvb:xyzvc:e,f,gva:a:b:cvb:x-y-zvc:efg从结果可以看出,当$IFS为:时,字符串"a:b:c"被解析为abc当$IFS为-时,字符串"x-y-z"被解析为xyz当$IFS为,时,字符串"e,f,g"被解析intoefg$HOME,$USER,$UID,$GROUPSHOME:用户主目录USER:当前用户名UID:当前用户IDGROUPS:当前用户组ID[tt@ecs-centos-7~]$echo$HOME/home/tt[tt@ecs-centos-7~]$echo$USERtt[tt@ecs-centos-7~]$echo$UID1003[tt@ecs-centos-7~]$echo$GROUPS1003$HOSTTYPE、$MACTYPE、$OSTYPE这些变量都表示系统硬件[tt@ecs-centos-7~]$echo$HOSTTYPEx86_64[tt@ecs-centos-7~]$echo$MACHTYPEx86_64-redhat-linux-gnu[tt@ecs-centos-7~]$echo$OSTYPElinux-gnu总结本文介绍一些常用的usedBash内置变量。对于一些不常用或者很少用到的变量,可以自行查阅相关资料。
