Shell 三三两两
Posted gageshen
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Shell 三三两两相关的知识,希望对你有一定的参考价值。
在Shell脚本中或多或少遇到$1-$9 , $0 , $? , $! , $$ , $*, $# , $@ 这些特殊意义的命令符。如果你是一位初学者,那么恭喜你看它就像看老道写的符箓,有点摸不着边?是要死记硬背?还是理解一下再记忆呢?我想还是理解一下再记吧!
简要说明一下:
一、与参数相关: $1-$9 , $0 ,$# , $*, $@
1)$1-$9 表给Shell的第几个参数:
在计算机语言编写一段代码总会涉及到什么形参、实参,即一段代码需要传递参数来保持灵活性。那么我们在编写shell脚本时,实际上就是实现一段功能的脚本代码,为了应对脚本灵活性那么就需要参数,那么参数们在shell脚本中使用时总要一个编号吧,否则怎么知道你是第一个,他是第二个……。现在shell爸爸说了,$1就表示第一个参数,$2就表示第2个参数,以此类推到$9表示第9个参数了;那么还要给shell脚本第10个,第11个……怎么办?shell爸爸说前面我有点考虑不足,$10到底表示第一参数$1值再加个0呢?还是第10个参数?所以shell规定了,要表示第10个,第11个……用$包围起来,$10表示第10个参数,$11表示第11个参数,……以此类推。
2) $0 表示执行本Shell的脚本/命令的名称。
前面$1-$9表示给shell脚本的第几个参数,那么谁需要这些参数呢?这不简单,还有谁要啊?不就是我们编写的shell脚本需要参数嘛!那么$0就是表示这位需要参数的shell脚本奶爸。也正因为这shell奶爸需要参数,所以也就在$0这奶爸的带领下有了$1,$2……$9一群参数。下面编写一个shell脚本说明一下$0和$1-$9:
1 [root@ecs-jumperserver ~]# mkdir /shell 2 [root@ecs-jumperserver ~]# cd /shell 3 [root@ecs-jumperserver shell]#vim myPapaShell.sh 4 #!/bin/bash 5 6 echo "IamPapa:$0" 7 echo "IamParameter1: $1" 8 echo "IamParameter2: $2" 9 echo "IamParameter3: $3" 10 11 [root@ecs-jumperserver shell]#chmod +x myPapaShell.sh 12 [root@ecs-jumperserver shell]#./myPapaShell.sh firstPara secondPara thirdPara 13 IamPapa: ./myPapaShell.sh 14 IamParameter1: firstPara 15 IamParameter2: secondPara 16 IamParameter3: thirdPara
3)$# 表示传给shell脚本的参数个数,即传了几个参数给shell脚本(#符号看上去有点像算盘)。
现在shell脚本奶爸不好当啊,有些时候它能量大一下子聚了好多参数,有时候能量不足,只聚了两三只小猫。shell脚本老爸这下犯愁了,谁知道给我传了多少个参数。这时$#手拿大算盘噼里啪啦就给shell脚本老爸知道现在有多少个参数。
4)$* 和$@ 表示所有参数列表
当看到*符号时,就想到所有。特别在匹配中表示任意字符就全部概念;而看到@就想到微信、QQ中@all,而shell脚本中又能@谁?@只能是参数。$* 和$@ 都是列举出所有传给shell脚本奶爸的参数。但是$* 和$@还是存在区别,区别如下:
$* 和 $@ 都表示传递给函数或脚本的所有参数,不被双引号(" “)包含时,都以"$1" "$2"……"$n"的形式输出所有参数。
但是当$* 和 $@被双引号(" “)包含时就不同了,"$*" 会将所有的参数作为一个整体,以"$1 $2 …$n"的形式输出所有参数;而"$@" 则会将各个参数分开,以"$1" "$2"……"$n"的形式输出所有参数。$@就像微信和QQ中@一样,不仅支持@all还能@各分开的参数。
下面列举一个shell脚本说明$# ,$* ,$@
[root@ecs-jumperserver shell]# cd /shell [root@ecs-jumperserver shell]# vim myParaShell.sh #!/bin/bash echo "Count the Parameter: $#" echo ‘###### $* ########‘ for i in $* ;do let j++ echo "Parameter$j: $i" done j=0 echo ‘###### $@ ########‘ for i in $@ ;do let j++ echo "Parameter$j: $i" done j=0 echo ‘###### "$*" ########‘ for i in "$*" ;do let j++ echo "Parameter$j: $i" done j=0 echo ‘###### "$@" ######‘ for i in "$@" ;do let j++ echo "Parameter$j: $i" done [root@ecs-jumperserver shell]# chmod +x myParaShell.sh [root@ecs-jumperserver shell]# ./myParaShell.sh first Count the Parameter: 1 ###### $* ######## Parameter1: first ###### $@ ######## Parameter1: first ###### "$*" ######## Parameter1: first ###### "$@" ###### Parameter1: first [root@ecs-jumperserver shell]# ./myParaShell.sh first second Count the Parameter: 2 ###### $* ######## Parameter1: first Parameter2: second ###### $@ ######## Parameter1: first Parameter2: second ###### "$*" ######## Parameter1: first second ###### "$@" ###### Parameter1: first Parameter2: second
二、与进程号PID相关 $$ , $!
1) $$ 表示shell脚本运行的当前进程PID号。
2) $! 表示shell脚本最后运行的后台进程的PID(通过jobs查看的后台进程),即后台运行的最后一个进程的进程PID号。
注:$! 仅仅针对在运行本shell脚本中的后台进程的PID记录,它是一个局部变量的概念。通俗讲如果shell脚本中含有$!,那么它只记录当前shell脚本运行期间开启的最后一个后台进程PID。shell脚本之后台进程变化它一律不管,相互隔离。($1-$9 , $0 , $? , $! , $$ , $*, $# , $@ 都是局部变量个概念,都是只记录当前shell脚本运行期间内容值。)
注:即使现在jobs中已经没有后台进程了,如执行完毕等,$!还会保留最后一个(最新一次加入的)后台运行进程的PID号,直到有最新的后台进程加入时才会更新$!。
1 [root@ecs-jumperserver shell]# vim myProcShell.sh 2 #!/bin/bash 3 4 echo "the shell script PID: $$" 5 6 sleep 600 & 7 sleep 60 & 8 echo "the last job PID: $!" 9 [root@ecs-jumperserver shell]# chmod +x myProcShell.sh 10 [root@ecs-jumperserver shell]# ./myProcShell.sh 11 the shell script PID: 5861 12 the last job PID: 5863 13 [root@ecs-jumperserver shell]# 14 [root@ecs-jumperserver shell]# cp myProcShell.sh myProcShell1.sh 15 [root@ecs-jumperserver shell]# vim myProcShell1.sh 16 #!/bin/bash 17 18 echo "the shell script PID: $$" 19 20 echo "the last job PID: $!" 21 [root@ecs-jumperserver shell]# chmod +x myProcShell1.sh 22 [root@ecs-jumperserver shell]# sleep 600 & 23 [1] 5893 24 [root@ecs-jumperserver shell]# ./myProcShell1.sh 25 the shell script PID: 5894 26 the last job PID: #$!仅针对运行的本shell的后台进程PID记录。 27 [root@ecs-jumperserver shell]#
三、结束代码 $?
1) $? 表示最后运行的命令的结束代码(返回值),即执行上一个指令的返回值(显示最后命令的退出状态)
其中指令的返回值:
0 :表示正常,没有错误。
其他值(非0) :表示是有错误,具体是什么错误查看该指令的帮助。
[root@ecs-jumperserver shell]# vim myCommandShell.sh #!/bin/bash echo "last command status: $?" num=2 [ $num -lt 3 ] echo "$num < 3:$?" [ $num -gt 3 ] echo "$num > 3:$?" [root@ecs-jumperserver shell]# chmod +x myCommandShell.sh [root@ecs-jumperserver shell]# x=2 [root@ecs-jumperserver shell]# [ $x -lt 0 ] [root@ecs-jumperserver shell]# ./myCommandShell.sh last command status: 0 2 < 3:0 2 > 3:1 [root@ecs-jumperserver shell]# [ $x -lt 0 ] [root@ecs-jumperserver shell]# echo $? 1 [root@ecs-jumperserver shell]#
小结:
$1-$9 , $0 , $? , $! , $$ , $*, $# , $@ 都是局部变量概念,只记录当前shell脚本运行期间的内容。在这些内容中可以把分层三类:与参数相关的,与进程相关的 和 与指令结束代码相关的。
参考:
https://blog.csdn.net/baidu_28126759/article/details/87863361
https://blog.csdn.net/xgt_520/article/details/78738320
https://www.runoob.com/linux/linux-shell-passing-arguments.html
以上是关于Shell 三三两两的主要内容,如果未能解决你的问题,请参考以下文章