三、Shell变量之三Shell进程中的特殊状态变量
$?: 获取执行上一个指令的执行状态返回值(0为成功,非0为失败) 通常用法: 1)判断命令、脚本或函数等程序是否执行成功。 2)若在脚本中调用执行“exit数字”,则会返回这个数字给“$?”变量。 3)如果是在函数里,则通过“return数字”把这个数字以函数返回值的形式传给“$?”。 $$: 获取当前执行的shell脚本的进程号(PID) $!: 获取上一个在后台工作的进程的进程号(PID) $_: 获取在此之前的命令或脚本的最后最后一个参数
1、$?
[root@node1 ~]# ls /tmp test2.sh test3.sh test.sh [root@node1 ~]# echo $? 0 [root@node1 ~]# ls /tmp/sss ls: cannot access /tmp/sss: No such file or directory [root@node1 ~]# echo $? 2 #/tmp/sss该文件不存在,返回值非0
获取脚本执行的进程号(PID)。
[root@node1 tmp]# cat /tmp/test_pid.sh #! /bin/bash echo $$ > /tmp/a.txt sleep 100 [root@node1 tmp]# bash /tmp/test_pid.sh [root@node1 ~]# cat /tmp/a.txt 13249 中止脚本后,再次运行脚本 [root@node1 tmp]# bash /tmp/test_pid.sh [root@node1 ~]# cat /tmp/a.txt 13299 #PID已发生变化
说明:有时执行定时任务脚本的频率比较快,并不知道上一个脚本是否真的执行完毕,但是,业务要求同一时刻只能有一个同样的脚本在运行,此时就可以利用$$获取上一次运行的脚本进程号,当程序重新运行时,根据获得的进程号,清理掉上一次的进程,运行新的脚本命令。
[root@node1 tmp]# cat /tmp/test_pid.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 #<==将当前Shell进程号记录到pid文件里。 sleep 300
[root@node1 tmp]# bash test_pid.sh [root@node1 ~]# ps -ef |grep test_pid.sh|grep -v test_pid.sh [root@node1 ~]# ps -ef |grep test_pid.sh|grep -v grep root 13489 12762 0 17:40 pts/0 00:00:00 bash test_pid.sh
多次运行,每次都会把上一次的pid杀掉,保障只有一个脚本在运行
[root@node1 tmp]# bash test_pid.sh & [1] 13618 [root@node1 tmp]# ps -ef |grep test_pid.sh|grep -v grep \root 13618 12762 0 17:43 pts/0 00:00:00 bash test_pid.sh [root@node1 tmp]# bash test_pid.sh & [2] 13641 [root@node1 tmp]# ps -ef |grep test_pid.sh|grep -v grep root 13641 12762 0 17:43 pts/0 00:00:00 bash test_pid.sh [1]- Terminated bash test_pid.sh [root@node1 tmp]# bash test_pid.sh & [3] 13653 [root@node1 tmp]# ps -ef |grep test_pid.sh|grep -v grep root 13653 12762 0 17:43 pts/0 00:00:00 bash test_pid.sh [2]- Terminated bash test_pid.sh
$_的作用是获得上一条命令的最后一个参数值
[root@node1 tmp]# cat /tmp/test2.sh #! /bin/bash echo $1 echo $2 [root@node1 tmp]# bash /tmp/test2.sh ywx1 ywx2 ywx3 ywx4 ywx1 ywx2 [root@node1 tmp]# echo $_ ywx4
4.$!
获取上一次执行脚本的pid
[root@node1 tmp]# cat /tmp/test_pid.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 #<==将当前Shell进程号记录到pid文件里。 sleep 300 [root@node1 tmp]# bash test_pid.sh & [5] 13901 [root@node1 tmp]# ps -ef |grep test_pid.sh|grep -v grep root 13901 12762 0 17:48 pts/0 00:00:00 bash test_pid.sh [4]- Terminated bash test_pid.sh [root@node1 tmp]# bash test_pid.sh & [6] 13914 [root@node1 tmp]# ps -ef |grep test_pid.sh|grep -v grep root 13914 12762 0 17:48 pts/0 00:00:00 bash test_pid.sh [5]- Terminated bash test_pid.sh [root@node1 tmp]# bash test_pid.sh & [7] 13923 [root@node1 tmp]# ps -ef |grep test_pid.sh|grep -v grep root 13923 12762 0 17:48 pts/0 00:00:00 bash test_pid.sh [6]- Terminated bash test_pid.sh [root@node1 tmp]# echo $! 13923
I have a dream so I study hard!!!