Shell中的特殊位置参数变量全文收录
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 dabiaoge2br/>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
[[email protected] ~]#
说明:两次测试结果两者完全一样,甚至“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
说明:$_就是上一条命令的最后一个参数值。
以上是关于Shell中的特殊位置参数变量全文收录的主要内容,如果未能解决你的问题,请参考以下文章