加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Shell中的特殊位置参数变量全文收录

发布时间:2020-12-15 23:06:41 所属栏目:安全 来源:网络整理
导读:一、位置参数变量的作用 一句话概括:我们要从命令行、函数或者脚本执行等处传递参数时,就需要在shell脚本中使用位置参数变量 二、Shell中的特殊未知参数变量有哪些 1) $0 作用:获取当前执行的shell脚本的脚本名字(如果脚本中包含了路径,那获取的就是脚
一、位置参数变量的作用

一句话概括:我们要从命令行、函数或者脚本执行等处传递参数时,就需要在shell脚本中使用位置参数变量

二、Shell中的特殊未知参数变量有哪些

1)$0
作用:获取当前执行的shell脚本的脚本名字(如果脚本中包含了路径,那获取的就是脚本路径)

2)$n
作用:获取当前执行的shell脚本的第n个参数(n=1..9),当n=0时,则就是$0获取脚本名,当n≥10,则必须使用{},例如:${10},当n有多个时,则参数之间用空格隔开

3)$#
作用:获取当前执行的shell脚本后面接的参数的总个数

4)$*
作用:获取当前执行的shell脚本后面所有的参数,如果给$*加上双引号,即"$*"时,则表示把所有的参数视为不同的单个字符串,相当于:"$1 $2 $3"

5)[email?protected]
作用:获取当前执行的shell脚本后面所有的参数,如果给[email?protected]加上双引号,即"[email?protected]"时,则表示把所有的参数视为不同的独立字符串,相当于:"$1" "$2" "$3",这种方式是把多参数传递给其他程序的最佳方式,因为它会保留所有的内嵌在每个参数里的任何空白

特殊说明:当"$*""[email?protected]"都加双引号时是有区别的,当两者都不加双引号时,是完全没区别的

6)$?
作用:获取执行上一个指令的执行状态返回值(0为成功,非0为失败,??这个变量非常的常用??)

7)$$
作用:获取当前执行的shell脚本的进程号(即PID),不太常用,了解即可

8)$!
作用:获取上一个在后台工作的进程的进程号,不太常用,了解即可

9)$_
获取在此之前执行的命令或脚本的最后的一个参数,类似于我们使用的快捷键“esc+.”,因为是在非交互模式下,所以使用$_,一般常用,了解即可

三、分别举例说明9个特殊位置参数变量

1)$0
[[email?protected] ~]# vim abc.sh
[[email?protected] ~]# cat abc.sh
echo $0
[[email?protected] ~]# sh abc.sh
abc.sh
[[email?protected] ~]# sh /root/abc.sh
/root/abc.sh
如果想单独获取脚本名或者路径,则配合下面的小命令:
[[email?protected] ~]# basename /root/abc.sh
abc.sh
关于basename的详细讲解,请浏览地址:
http://blog.51cto.com/zpf666/2335218
[[email?protected] ~]# dirname /root/abc.sh
/root
关于dirname的详细讲解,请浏览地址:
http://blog.51cto.com/zpf666/2335223
说明:若不带路径执行脚本,则输出的结果就是脚本名;
如果使用全路径执行脚本,那么输出的结果就是全路径+脚本名

2)$n
[[email?protected] ~]# vim abc.sh
[[email?protected] ~]# cat abc.sh
echo $1
[[email?protected] ~]# sh abc.sh dabiaoge
dabiaoge
[[email?protected] ~]# vim abc.sh
[[email?protected] ~]# cat abc.sh
echo $1 $2
[[email?protected] ~]# sh abc.sh dabiaoge dabiaoge2
dabiaoge dabiaoge2
[[email?protected] ~]# vim abc.sh
[[email?protected] ~]# cat abc.sh
echo $1 $2 $3
[[email?protected] ~]# sh abc.sh "dabiaoge dabiaoge2" dabiaoge3 dabiaoge4
dabiaoge dabiaoge2 dabiaoge3 dabiaoge4
说明:⑴参数与参数之间用空格隔开
⑵加引号括起来的参数会作为一个字符串看待
[[email?protected] ~]# echo ${1..15} > num.sh
[[email?protected] ~]# cat num.sh
$1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15
[[email?protected] ~]# vim num.sh
[[email?protected] ~]# cat num.sh
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15
[[email?protected] ~]# sh num.sh {a..z}
a b c d e f g h i a0 a1 a2 a3 a4 a5
为什么会出现a0 a1 a2 a3 a4 a5,而不是字母呢?这是因为前面提过的,当n≥10,则必须使用{},例如:${10},请看下面:
[[email?protected] ~]# vim num.sh
[[email?protected] ~]# cat num.sh
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12} ${13} ${14} ${15}
[[email?protected] ~]# sh num.sh {a..z}
a b c d e f g h i j k l m n o
说明:⑴当n≥10,则必须使用{}
⑵生产环境下规范的写法是"$1" "$2" "$3",就是$n用双引号括起来

3)$#
[[email?protected] ~]# vim abc.sh
[[email?protected] ~]# cat abc.sh
echo $#
[[email?protected] ~]# sh abc.sh {a..z}
26
条件表达式判断语句的写法(例子):
[[email?protected] ~]# vim tt1.sh
[[email?protected] ~]# cat tt1.sh

#!/bin/bash                             
[ $# -ne 2 ] && {                  //“-ne”是不等于的意思,“-eq”是等于的意思
echo "必须两个参数"
exit 1
}
echo dabiaoge_nb

[[email?protected] ~]# sh tt1.sh dabiaoge1
必须两个参数
[[email?protected] ~]# sh tt1.sh dabiaoge1 dabiaoge2
dabiaoge_nb
if判断语句的写法(例子):
[[email?protected] ~]# vim tt2.sh
[[email?protected] ~]# cat tt2.sh

#!/bin/bash
if [ $# -ne 2 ]
then
echo "用法:/bin/sh $0 参数1 参数2"             //注意此处的$0,打印脚本名
exit 1
fi
echo $1 $2

[[email?protected] ~]# sh tt2.sh dabiaoge1
用法:/bin/sh tt2.sh 参数1 参数2
[[email?protected] ~]# sh tt2.sh dabiaoge1 dabiaoge2
dabiaoge1 dabiaoge2

4)$*和[email?protected]
举例说明的材料:
[[email?protected] ~]# set -- "I am" big biaoge //“set --”表示清除所有的参数变量,重新设置后面的参数变量
[[email?protected] ~]# echo $#
3
[[email?protected] ~]# echo $1
I am
[[email?protected] ~]# echo $2
big
[[email?protected] ~]# echo $3
biaoge
测试①:两者都不带双引号
普通测试:
[[email?protected] ~]# echo $*
I am big biaoge
[[email?protected] ~]# echo [email?protected]
I am big biaoge
使用for循环测试:
[[email?protected] ~]# for i in $*;do echo $i;done
I
am
big
biaoge
[[email?protected] ~]# for i in [email?protected];do echo $i;done
I
am
big
biaoge
说明:两次测试结果两者完全一样,甚至“I am”这第一个参数也给分开了。
测试②:两者都带双引号
普通测试:
[[email?protected] ~]# echo "$*"
I am big biaoge
[[email?protected] ~]# echo "[email?protected]"
I am big biaoge
使用for循环测试:

[[email?protected] ~]# for i in "$*";do echo $i;done
I am big biaoge
[[email?protected] ~]# for i in "[email?protected]";do echo $i;done
I am
big
biaoge
[[email?protected] ~]# for i;do echo $i;done
I am
big
biaoge

说明:当普通测试的时候还是完全没区别,一旦使用for循环测试,就出现了不同之处。即:在for循环+双引号的情况下,$*和[email?protected]是不一样的
去掉"in 变量列表",相当于有引号的in "[email?protected]"。
5)$?
[[email?protected] ~]# pwd
/root
[[email?protected] ~]# echo $?
0
[[email?protected] ~]# ls /dabiaoge
ls: cannot access /dabiaoge: No such file or directory
[[email?protected] ~]# echo $?
2
说明:在生产环境下,$?返回值的用法:
①判断命令、脚本或函数等程序是否执行成功
②若在脚本中调用执行“exit 数字”,则会返回这个数字给“$?”变量
③如果是在函数里面,则通过“return 数字”把这个数字以函数返回值的形式传给“$?”
6)$$
[[email?protected] ~]# vim test_pid.sh
[[email?protected] ~]# cat test_pid.sh
echo $$ > /tmp/abc.pid
sleep 300
[[email?protected] ~]# ps -ef | grep test_pid | grep -v grep
[[email?protected] ~]# sh test_pid.sh &
[1] 13107
[[email?protected] ~]# ps -ef | grep test_pid | grep -v grep
root 13107 3977 0 22:01 pts/0 00:00:00 sh test_pid.sh
[[email?protected] ~]# cat /tmp/abc.pid
13107
说明:通过ps看到的脚本的进程号13107与/tmp/abc.pid里面的数字是一样的,这就是靠$$传参过来的值。
一般运用场景:有时执行定时任务脚本的频率比较快,并不知道上一个脚本是否真的执行完毕,但是,业务要求同一时刻只能有一个同样的脚本在运行,此时就需要利用$$来获取上一次运行的脚本进程号,当程序重新运行时,根据获取的进程号,清理掉上一次的进程。举例脚本如下:
[[email?protected] ~]# cat pid.sh

#!/bin/bash
pidpath=/tmp/ceshi.pid
#如果pid文件存在,则执行then后面的命令
if [ -f "$pidpath" ]
   then
#杀掉与前一个进程号对应的进程
    kill $(cat $pidpath) > /dev/null 2&>1
    rm -rf $pidpath
fi
echo $$ > $pidpath
sleep 300

[[email?protected] ~]# ps -ef | grep pid.sh | grep -v grep
[[email?protected] ~]# sh pid.sh &
[1] 13580
[[email?protected] ~]# ps -ef | grep pid.sh | grep -v grep
root 13580 3977 0 22:13 pts/0 00:00:00 sh pid.sh
[[email?protected] ~]# sh pid.sh &
[2] 13592
[[email?protected] ~]# ps -ef | grep pid.sh | grep -v grep
root 13592 3977 0 22:13 pts/0 00:00:00 sh pid.sh
[1]- Terminated sh pid.sh
[[email?protected] ~]# sh pid.sh &
[3] 13603
[[email?protected] ~]# ps -ef | grep pid.sh | grep -v grep
root 13603 3977 0 22:13 pts/0 00:00:00 sh pid.sh
[2]- Terminated sh pid.sh
7)$!
[[email?protected] ~]# ps -ef | grep pid.sh | grep -v grep
[[email?protected] ~]# sh pid.sh &
[1] 13806
[[email?protected] ~]# echo $!
13806
[[email?protected] ~]# ps -ef | grep pid.sh | grep -v grep
root 13806 3977 0 22:18 pts/0 00:00:00 sh pid.sh
说明:$!的功能类似于$$,只不过作用是获取上一次执行脚本的pid
8)$_
[[email?protected] ~]# systemctl restart nginx.service
[[email?protected] ~]# systemctl restart nginx.service
[[email?protected] ~]# echo $_nginx.service说明:$_就是上一条命令的最后一个参数值。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读