Shell编程之特殊变量和扩展变量详解
特殊变量
在Shell中的特殊变量主要分别两种位置参数变量、状态变量两种。
位置参数变量
Shell中的位置参数变量主要是指0、0、1、$#等,主要用于从命令行、函数或脚本执行等地方传递参数。详细说明如下所示:
- $0:获取当前执行的Shell脚本的文件名,如脚本中包含路径,则输出也包括路径
- $n:获取当前执行的Shell脚本的第n个参数值,如n>9,则需要使用用大括号,如${10},各参数间用空格进行分隔
- $#:获取当前执行的Shell脚本传入参数的总个数
- $*:获取当前执行的Shell所有传入参数,如不加引号则与$@功能相同,如果添加双引号**"∗",则表示将所有传入参数视为单个字符串∗∗,相当于"∗",则表示将所有传入参数视为单个字符串∗∗,相当于"1223"
- $@:获取当前执行的Shell所有传入参数,**如不加引号则与$*功能相同,如果添加双引号"@",则表示将所有传入参数视为独立的字符串∗∗,相当于"@",则表示将所有传入参数视为独立的字符串∗∗,相当于"1""2""2""3"
当"∗"和"∗"和"@"都添加双引号时,两者的功能有所区别;如不加,则功能相同,无区别。
位置参数变量示例
1、示例一:
[root@localhostTest]#catpara.sh #!/bin/bash echo$1$2$3$4$5$6$7$8$9${10}${11}${12}${13}${14}${15} echo'$0is:'$0 echo'$1is:'$1 echo'$12is:'${12} echo'$#is:'$# echo'$*is:'$* echo'"$*"is:'"$*" echo'$@is:'$@ echo'"$@"is:'"$@" #输出结果 [root@localhostTest]#bash~/Test/para.sh{a..z} abcdefghijklmno $0is:/root/Test/para.sh $1is:a $12is:l $#is:26 $*is:abcdefghijklmnopqrstuvwxyz "$*"is:abcdefghijklmnopqrstuvwxyz $@is:abcdefghijklmnopqrstuvwxyz "$@"is:abcdefghijklmnopqrstuvwxyz
1、传入的参数个数多于脚本定义的参数时,则多出的参数会忽略
2、传入的参数中如使用双引号,则会当作一个参数值进行传递
3、位置参数如大于9,需要使用${}进行传递
2、示例二:
[root@localhostTest]#cattestposition.sh #!/bin/bash echo'$#$1$2$3$*$@' echo$#$1$2$3$*$@ echo"************" echo'$*' fortmpin$* do echo$tmp done echo"************" echo"@@@@@@@@@@@@" echo'$@' fortempin$@ do echo$temp done echo"@@@@@@@@@@@@" echo'"*"*"*"*"*"*' echo'$*' foriin"$*" do echo$i done echo'"*"*"*"*"*"*' echo'"@"@"@"@"@"@' echo'$@' forjin"$@" do echo$j done echo'"@"@"@"@"@"@' [root@localhostTest]#bashtestposition.sh"HelloJack"Welcome"toShanghai" $#$1$2$3$*$@ 3HelloJackWelcometoShanghaiHelloJackWelcometoShanghaiHelloJackWelcometoShanghai ************ $*#未加双引号,所以会输出全部参数,则第一个和第三个参数会拆开 Hello Jack Welcome to Shanghai ************ @@@@@@@@@@@@ $@#未加双引号,所以会输出全部参数,则第一个和第三个参数会拆开 Hello Jack Welcome to Shanghai @@@@@@@@@@@@ "*"*"*"*"*"* $*#添加双引号后,传入的参数全部当一个参数进行输出 HelloJackWelcometoShanghai "*"*"*"*"*"* "@"@"@"@"@"@ $@#添加双引号后,传入的参数全部当独立的参数进行输出 HelloJack Welcome toShanghai "@"@"@"@"@"@
状态变量
- $?:获取上一个命令或脚本的执行状态值(0:成功,其他:失败)
- $$:获取当前执行的Shell的进程号(PID)
- $!:获取上一个在后台工作的进程的进程号
- **$_**:获取在些之前执行的命令或脚本的最后一个参数
以上四个状态变量,仅$?常用,其他三个了解即可。
在日常使场景中,$?主要用法如下所示:
1、判断命令和脚本是否执行成功
2、如脚本中调用exit数字,则会返回该数字给$?
3、如在函数中,则可以通过return数字将该数字返回给$?
状态变量示例
1、$?示例:
[root@localhostTest]#ll/etc/profile -rw-r--r--.1rootroot18194月112018/etc/profile [root@localhostTest]#echo$? 0 [root@localhostTest]#ll/etc/profild ls:无法访问/etc/profild:没有那个文件或目录 [root@localhostTest]#echo$? 2
2、$$示例:
[root@localhostTest]#cattestPID.sh #!/bin/bash echo$$>/tmp/test.pid sleep300 [root@localhostTest]#bashtestPID.sh将当前脚本调用到后台执行 [1]1671 [root@localhostTest]#ps-ef|greptestPID|grep-vgrep root167123706016:37pts/000:00:00bashtestPID.sh#查询PID
3、!示例:!示例:!功能类似于$$,只不过是获取上一次执行脚本的PID
[root@localhostTest]#bashtestPID.sh& [1]24078 [root@localhostTest]#echo$! 24078#打印上一次在后台执行的进程号 [root@localhostTest]#ps-ef|greptestPID|grep-vgrep root2407823706016:42pts/000:00:00bashtestPID.sh
4、$_示例:
[root@localhostTest]#bashpara.sh{a..z} abcdefghijklmno $0is:para.sh $1is:a $12is:l $#is:26 $*is:abcdefghijklmnopqrstuvwxyz "$*"is:abcdefghijklmnopqrstuvwxyz $@is:abcdefghijklmnopqrstuvwxyz "$@"is:abcdefghijklmnopqrstuvwxyz [root@localhostTest]#echo$_ z#打印最后一个传入的参数值
Bash内置变量
常用的内部命令有echo、eval、exec、export、read、shift、exit。
echo
主要用于打印信息,其命令格式如下所示:
echo[options]args
常用参数如下所示:
参数选项 | 说明 |
---|---|
-n | 不换行输出内容 |
-e | 解析转义字符 |
echo常用转义字符如下:
转义字符 | 说明 |
---|---|
\n | 换行 |
\r | 回车 |
\t | Tab |
\b | 退格 |
\v | 纵向制表符 |
eval
当Shell程序运行到eval语句时,将读入参数args,并将它们组合成一个新的命令而后执行。其命令格式如下所示:
evalargs
exec
exec主要用于在不创建新的子进程的情况下,转而执行指定的命令,当指定命令执行完后,则终止该进程。其命令格式如下所示:
execargs
当使用exec打开文件后,read命令每次都会将文件指针移动到下一行进行读取,直至结束。因此常用来处理文件内容。
read
从标准输入读取变量或字符串等信息并传递给其他变量,其命令格式如下所示
readargs
shift
对传入的位置参数依次向左移动一个位置,并使用位置参数$#减1,直至0为止。其命令格式如下所示:
shiftpostitionargs
shift如果不带参数,则默认左移1位
如传入的参数为1123,如执行一次shift,则之前的3,如执行一次shift,则之前的3变成2,2,2变成1,1,1消失。
exit
常用于退出Shell,在日常使用过程中可使用exitnum来自定义返回状态数。
Bash内置变量示例
1、echo
[root@localhostTest]#echo"Test";echo"Dao" Test Dao [root@localhostTest]#echo-n"Test";echo"Dao" TestDao [root@localhostTest]#echo-e"Test\tName\nDao" TestName Dao
2、eval
[root@localhostTest]#cateval.sh #!/bin/bash echo"Noeval" echo\$$# echo"Addeval" evalecho\$$# [root@localhostTest]#basheval.shab Noeval $2#未添加evel时,$#为2,则输出$2 Addeval b#添加evel后,则重新对传入的参数进行解析,则输出传入的第2个参数
3、exec
[root@localhostTest]#execls eval.shpara.shping.shtestPID.shtestposition.sh [admin@localhost~]$#在执行exec后则终止当前Shell进程,因此从root用户退出到普通用户 #与read一起读取文件 [root@localhost~]#seq5>/tmp/rand.log [root@localhost~]#cat/tmp/rand.log 1 2 3 4 5 [root@localhostTest]#catexec.sh #!/bin/bash exec4、read
可以参考公众号中read命令一文
5、shift
[root@localhostTest]#catshift.sh #!/bin/bash echo$1$2$3$4$5 until[-z$1] do echo$@ shift1 done [root@localhostTest]#bashshift.sh{1..5} 12345 12345 2345 345 45 5变量扩展
变量扩展说明
Shell中变量扩展说明如下所示:
- ${var}:返回${var}的内容
- ${#var}:返回${var}的字符长度
- ${var:offset}:返回${var}从位置offset之后开始提取字符至结束
- ${var:offset:length}:返回${var}从offset之后,提取长度为length的字符
- ${var#word}:返回从${var}开头开始删除最短匹配的word子符串
- ${var##word}:返回从${var}开头开始删除最长匹配的word子符串
- ${var%word}:返回从${var}结尾开始删除最短匹配的word子符串
- ${var%%word}:返回从${var}结尾开始删除最长匹配的word子符串
- ${var/oldstring/newstring}:使用newstring替换第一个匹配的字符oldstring
- ${var//oldstring/newstring}:使用newstring替换所有匹配的字符oldstring
- ${var:-word}:如果变量var的值为空或未赋值,则将word做为返回值,常用于防止变量为空或未定义而导致的异常
- ${var:=word}:如果变量var的值为空或未赋值,则将word赋值给var并返回其值。
- ${var:?word}:如果变量var的值为空或未赋值,则将word做为标准错误输出,否则则输出变量的值,常用于捕捉因变量未定义而导致的错误并退出程序
- ${var:+word}:如果变量var的值为空或未赋值,则什么都不做,否则word字符将替换变量的值
其中${var:-word}、${var:=word}、${var:?word}、${var:+word}中的冒号也可以省略,则将变量为空或未赋值修改为未赋值,去掉了为空的检测,即运算符仅检测变量是否未赋值
变量扩展示例
[root@localhostinit.d]#var="Thisisteststring" [root@localhostinit.d]#echo$var Thisisteststring [root@localhostinit.d]#echo${var} Thisisteststring [root@localhostinit.d]#echo${#var}#统计字符长度 19 [root@localhostinit.d]#echo${var:5}#从第5个位置开始截取字符 isteststring [root@localhostinit.d]#echo${var:5:2}#从第5个位置开始截取2个字符 is [root@localhostinit.d]#echo${var#This}#从开头删除最短匹配的字符is isteststring [root@localhostinit.d]#echo${var##This}#从开头删除最长匹配的字符is isteststring [root@localhostinit.d]#echo${var%g}#从结尾删除最短匹配的字符is Thisisteststrin [root@localhostinit.d]#echo${var%%g}#从结尾删除最长匹配的字符is Thisisteststrin [root@localhostinit.d]#echo${var/is/newis}#替换第一个匹配的字符 Thnewisisteststring [root@localhostinit.d]#echo${var//is/newis}#替换所有匹配到的字符 Thnewisnewisteststring [root@localhostinit.d]#echo$centos#变量未定义 [root@localhostinit.d]#echo${centos:-UNDEFINE}#变量为空,返回UNDEFINE UNDEFINE [root@localhostinit.d]#centos="CentOS" [root@localhostinit.d]#echo${centos:-UNDEFINE}#变量已经定义,返回变量本身的值 CentOS [root@localhostinit.d]#unsetcentos#取消变量值 [root@localhostinit.d]#echo$centos [root@localhostinit.d]#result=${centos:=UNDEFINE} [root@localhostinit.d]#echo$result UNDEFINE [root@localhostinit.d]#echo$centos#变量值为空,则将UNDEFINE赋值给centos UNDEFINE [root@localhostinit.d]#unsetcentos [root@localhostinit.d]#echo${centos:?cannotfindvariablecentos} -bash:centos:cannotfindvariablecentos#变量值为空,输出自定义错误信息 [root@localhostinit.d]#centos="ISDEFINED" [root@localhostinit.d]#echo${centos:?cannotfindvariablecentos} ISDEFINED#变量值已定义,则输出变量值 [root@localhostinit.d]#unsetcentos [root@localhostinit.d]#echo${centos:+donothing}#变量值为空,什么都不操作输出 [root@localhostinit.d]#centos="do" [root@localhostinit.d]#echo${centos:+donothing}#变量已赋值,则输出自定义的消息 donothing
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对毛票票的支持。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。