一、特殊位置参数变量

  1、特殊位置参数变量

    在shell中比如:$0、$1、$#,等被称为特殊位置参数变量,当命令行、函数、脚本执行等处传递参数时,就需要使用位置参数变量
    参数说明如下:
shell 学习笔记3-shell变量扩展 - 图1

  2、示例$1$2…$9${10}${11}…

    1)测试$n(n为1..15)
[root@web1 scripts]# vim test1.sh  #<—-创建test1.sh脚本
#!/bin/bash
echo $1  #<—-打印脚本传递的第一个参数的值
[root@web1 scripts]# chmod +x test1.sh  #<—-授权
[root@web1 scripts]# ./test1.sh  #<—-不加参数输出空白

[root@web1 scripts]# ./test1.sh zxg #<—-加一个参数
zxg
[root@web1 scripts]# ./test1.sh zxg shell #<—-加两个参数,只输出第一个参数
zxg
[root@web1 scripts]# ./test1.sh “zxg shell” #<—-添加双括号,两个都输出因为加双括号会作为一个字符串参数
zxg shell
[root@web1 scripts]#
    2)同时加入$1和$2,并进行测试
[root@web1 scripts]# cat test2.sh  #<—-创建test2.sh脚本
#!/bin/bash
echo $1 $2

[root@web1 scripts]# chmod +x test2.sh #<—-加权限
[root@web1 scripts]# ./test2.sh zxg shell #<—-运行
zxg shell  
[root@web1 scripts]# ./test2.sh “zxg shell” 2019 #<—-对又空格的字符串需要双引号才能正常使用
zxg shell 2019
[root@web1 scripts]#
    3)设置15个位置参数($1~$15),用于接收命令行传递的15个参数
[root@web1 scripts]# echo \${1..15} #<—-利用大括号输出15个位置参数,10大技巧
$1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15
[root@web1 scripts]# echo \${1..15} >test3.sh
[root@web1 scripts]# cat test3.sh
$1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15
[root@web1 scripts]# echo {a..z}
a b c d e f g h i j k l m n o p q r s t u v w x y z
[root@web1 scripts]# chmod +x test3.sh
[root@web1 scripts]# cat test3.sh
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15
[root@web1 scripts]# ./test3.sh {a..z} #<—-运行发现就到9 超过9必须用大括号
a b c d e f g h i a0 a1 a2 a3 a4 a5
[root@web1 scripts]#
[root@web1 scripts]# cat test3.sh
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12} ${13} ${14} ${15} #这样就可以正常了
[root@web1 scripts]# ./test3.sh {a..z}
a b c d e f g h i j k l m n o
[root@web1 scripts]#

  3、$0特殊变量的作用示例

    取出执行脚本的名称(包括路径)
    1)、获得脚本名称及路径
[root@web1 scripts]# cat test4.sh
#!/bin/bash
echo $0

[root@web1 scripts]# chmod +x test4.sh
[root@web1 scripts]# ./test4.sh
./test4.sh
[root@web1 scripts]#
[root@web1 scripts]# sh /scripts/test4.sh #<—-带路径的话,就会输出路径加名字
/scripts/test4.sh
[root@web1 scripts]#

    2)单独获取名称或路径的方法
[root@web1 scripts]# dirname /scripts/test4.sh #<—-dirname命令作用时获取脚本路径
/scripts
[root@web1 scripts]# basename /scripts/test4.sh #<—-basename命令则时获取脚本名称
test4.sh
[root@web1 scripts]#
    3)利用$0 和(dirname、basename)分别读取脚本名称和脚本路径
[root@web1 scripts]# cat test5.sh
#!/bin/bash
dirname $0
basename $0

[root@web1 scripts]# chmod +x test5.sh
[root@web1 scripts]# sh /scripts/test5.sh
/scripts
test5.sh
[root@web1 scripts]#

  4、$#特殊变量获取脚本传参个数的示例

    1)通过$#获取脚本传参的个数
[root@web1 scripts]# cat test6.sh
#!/bin/bash
echo $1 $2 $3 $4 $5 $6 $7 $8 $9
echo $#
[root@web1 scripts]# chmod +x test6.sh
[root@web1 scripts]# ./test6.sh {a..z} #<—-传入26个参数
a b c d e f g h i #<—-只打印了9个
26 #<—-代表26个参数
[root@web1 scripts]#
    2)根据用户在命令行的传参个数判断用户的输入,不合要求的给予提示并退出
      这是针对$0、$1、$#等多位置参数的综合示例
[root@web1 scripts]# cat test7.sh
#!/bin/bash
[ $# -ne 2 ] && { #<—-如果执行脚本传参的个数不等于2
echo “muse two args” #<—-则给用户提示正确的用法
exit 1 #<—-由于不满足要求,因此退出脚本,返回值为1
}
echo abc #<—-满足了参数个数的传参要求,就执行判断后的程序脚本,打印abc
[root@web1 scripts]# chmod +x test7.sh
[root@web1 scripts]# ./test7.sh
muse two args
[root@web1 scripts]# ./test7.sh 1 2
abc
[root@web1 scripts]#
      if语句的写法
[root@web1 scripts]# cat test8.sh
#!/bin/bash
if [ $# -ne 2 ]
then
echo “USAGE:/bin/bash $0 arg1 arg2”
exit 1
fi
echo $1 $2
[root@web1 scripts]# chmod +x test8.sh
[root@web1 scripts]# ./test8.sh
USAGE:/bin/bash ./test8.sh arg1 arg2
[root@web1 scripts]# ./test8.sh 1 3
1 3
[root@web1 scripts]#

  5、$*和$@特殊变量功能及区别示例

    1)利用set设置位置参数(同命令行脚本的传参)
[root@web1 scripts]# set — “i am” zxg shell
[root@web1 scripts]# echo $#
3
[root@web1 scripts]# echo $1
i am
[root@web1 scripts]# echo $2
zxg
[root@web1 scripts]# echo $3
shell
[root@web1 scripts]#
    测试$和$@,注意,此时带双引号
[root@web1 scripts]# echo “$

i am zxg shell
[root@web1 scripts]# echo “$@”
i am zxg shell
[root@web1 scripts]# for i in “$“;do echo $i;done #<—-在又双引号的情况下,”$“,引号里面当作一个参数输出
i am zxg shell
[root@web1 scripts]# for i in “$@”;do echo $i;done #<—-在又双引号的情况下,”$#”,每个参数独立输出,
i am #<—-算一个参数
zxg
shell
[root@web1 scripts]# for i ;do echo $i;done #<—-去掉in 变量列表,相当于又引号的in “$@”
i am
zxg
shell
[root@web1 scripts]# for i in $;do echo $i;done #<—-$不加双引号,因此会输出所有参数,然后第一个参数”i am”也拆开输出了
i
am
zxg
shell
[root@web1 scripts]# shift #<—-用shift将位置参数移位(左移)
[root@web1 scripts]# echo $#
2
[root@web1 scripts]# echo $1 #<—-这里就打印原来$2的值
zxg
[root@web1 scripts]# echo $2 #<—-这里就打印原来$3的值
shell
[root@web1 scripts]#

二、shell进程中的特殊状态变量

shell 学习笔记3-shell变量扩展 - 图2

  1、$?示例

    1)执行命令
[root@web1 scripts]# pwd
/scripts
[root@web1 scripts]# echo $? #<—-返回0表示上一个命令成功
0
[root@web1 scripts]# ls /root
anaconda-ks.cfg Desktop google-chrome-stable_current_x86_64.rpm original-ks.cfg
bash-test Downloads initial-setup-ks.cfg
[root@web1 scripts]# lss /root
bash: lss: command not found…
Similar command is: ‘ls’
[root@web1 scripts]# echo $? #<—-非零表示上一个命令失败
127
[root@web1 scripts]#
    可以利用$?判断安装、打包、备份等执行是否正确成功
      tar zcf /zxg/zxg.tar.gz /zxg/zxg
      echo $?

    2)通过脚本控制命令及脚本执行后的返回值
[root@web1 scripts]# cat test9.sh
#!/bin/bash
[ $# -ne 2 ] && { #<—-参数格式不等于2

  1. echo "must be two args" #<---输出提示<br />exit 119 #<---终止程序运行并以制定的119状态值退出程序赋值给$?<br />}<br />echo zxg

[root@web1 scripts]# chmod +x test9.sh
[root@web1 scripts]# ./test9.sh 1 2
zxg
[root@web1 scripts]# echo $?
0
[root@web1 scripts]# ./test9.sh
must be two args
[root@web1 scripts]# echo $?
119
[root@web1 scripts]#
    3)小结
      判断命令、脚本或函数程序是否执行成功
      若在脚本中调用执行exit 数字 把这个数字以函数返回值的形式传给$?变量
      如果是在函数里,则通过return数字把这个数字以函数返回值的形式传给$?

  2、$$特殊变量功能及实践

    1)获取脚本执行的进程号
[root@web1 scripts]# cat test10.sh
#!/bin/bash
echo >/tmpa.pid #<—-获取的值,并重定向
sleep 300 #<—-休息300s,模拟守护进程不退出
[root@web1 scripts]# chmod +x test10.sh
[root@web1 scripts]# ps -ef|grep test10|grep -v grep  
[root@web1 scripts]# ./test10.sh & #<—-后台运行
[1] 49825
[root@web1 scripts]# ps -ef|grep test10|grep -v grep #<—-查找进程号
root 49825 36709 0 18:23 pts/1 00:00:00 /bin/bash ./test10.sh
[root@web1 scripts]# cat /tmpa.pid  #<—-对应$$的值
49825
[root@web1 scripts]#
    2)实现系统中多次执行某个脚本后的进程只有一个-企业级应用,用于执行启动或定时任务
[root@web1 scripts]# cat test11.sh
#!/bin/bash
pidpath=/tmp/a.pid #<—-定义pid文件
if [ -f “$pidpath” ]  #<—-如果pid文件存在,值=则执行then后面的命令
then
kill cat $pidpath >/dev/null 2>&1 #<—-杀掉与前一个金朝赌赢的进程
rm -f $pidpath  #<—-删除pid文件
fi
echo $$ >$pidpath #<—-将当前$$值记录到pid文件里
sleep 300
[root@web1 scripts]# chmod +x test11.sh
[root@web1 scripts]# ./test11.sh
^C
[root@web1 scripts]# ./test11.sh &
[1] 49966
[root@web1 scripts]# ps -ef |grep test11.sh|grep -v grep
root 49966 36709 0 18:35 pts/1 00:00:00 /bin/bash ./test11.sh
[root@web1 scripts]# ./test11.sh &
[2] 49981
[root@web1 scripts]# ps -ef |grep test11.sh|grep -v grep
root 49981 36709 0 18:36 pts/1 00:00:00 /bin/bash ./test11.sh
[1]- Terminated ./test11.sh
[root@web1 scripts]# ./test11.sh & #<—-无论执行多少次脚本每次都会将上一次运行的杀掉,都只有一个进程
[3] 49988
[root@web1 scripts]# ps -ef |grep test11.sh|grep -v grep
root 49988 36709 0 18:36 pts/1 00:00:00 /bin/bash ./test11.sh
[2]- Terminated ./test11.sh
[root@web1 scripts]#

  3、$_特殊变量功能说明及实践

    获得上一条命令的最后一个参数,用的不多
[root@web1 scripts]# systemctl restart httpd zxg
Failed to restart zxg.service: Unit not found.
Job for httpd.service failed because the control process exited with error code. See “systemctl status httpd.service” and “journalctl -xe” for details.
[root@web1 scripts]# echo $_
zxg
[root@web1 scripts]#

  4、$!特殊变量功能说明及实践

    $!的功能类似$$,只不过作用是获取上次执行脚本的pid,了解就可以了
[root@web1 scripts]# ps -ef |grep test11.sh|grep -v grep
[root@web1 scripts]# echo $!
49988
[root@web1 scripts]#