2019-06-05shell笔记2

4.1.2 Shell进程中的特殊状态变量
表4-2针对Shell进程的特殊状态变量进行了说明。 表4-2 
Shell进程的特殊状态变量说明 提示查找上述知识
的方法为使用man bash命令,然后搜关键字“Special Parameters”。
 1.$?特殊变量功能实践 范例4-10:
执行命令后获取返回值(切换到oldboy用户下进行测试)。 
[oldboy@oldboy ~]$ pwd #<==执行pwd命令,
然后用“echo $?”查看执行命令的状态返回值。
/home/oldboy
[oldboy@oldboy ~]$ echo $?
0  #<==返回0,表示上一个命令的执行是成功的。
[oldboy@oldboy ~]$ ls /root #<==列表root目录的内容,
ls: cannot open directory /root: Permission denied  #<==提示权限不够。
[oldboy@oldboy ~]$ echo $?
2 #<==返回值为非0,表示上一个命令(ls /root)
执行错误。注意:对于不同的错误,返回值是
         不同的。
[oldboy@oldboy ~]$ rm -fr /root #<==删除/root目录及其子目录。
rm: cannot remove `/root': Permission denied       #<==提示权限不够。
[oldboy@oldboy ~]$ echo $?
1 #<==返回值为1(非0)。
[oldboy@oldboy ~]$ oldboy                     #<==执行一个不存在的命令。
-bash: oldboy: command not found              #<==提示命令找不到。
[oldboy@oldboy ~]$ echo $?
127 #<==返回值为127(非0)。

不同命令的执行结果中,“$?”的返回值不尽相同,
但在工作场景中,常用的就是0和非0两种状态,
0表示成功运行,非0表示运行失败。
 范例4-11:根据返回值来判断软件的安装步骤是否成功。
 若使用源码编译安装软件,可以在每个步骤的结尾获取“$?”来判断命令执行成功与否。
例如:编译Nginx Web服务软件,执行make命令之后,新手不太容易确定编译是否正确
,这时就可以使用“echo$?”命令查看其返回值是否为0。
下面是Nginx Web的基本安装过程
,其中就是通过获取命令的返回值来确定命令的执行状况的。
[root@oldboy tools]# yum install pcre-devel openssl-devel –y
[root@oldboy tools]# wget -q http://nginx.org/download/nginx-1.10.1.tar.gz
[root@oldboy tools]# tar xf nginx-1.10.1.tar.gz
[root@oldboy tools]# cd nginx-1.10.1
[root@oldboy nginx-1.10.1]# ./configure --prefix=/application/nginx-1.10.1 --user=nginx --group=nginx --with-http_ssl_module  --with-http_stub_status_module……省略部分配置过程
  nginx http proxy temporary files: "proxy_temp"
  nginx http fastcgi temporary files: "fastcgi_temp"
  nginx http uwsgi temporary files: "uwsgi_temp"
  nginx http scgi temporary files: "scgi_temp"
[root@oldboy nginx-1.10.1]# echo $?
0
[root@oldboy nginx-1.10.1]# make……省略部分编译过程
sed -e "s|%%PREFIX%%|/application/nginx-1.10.1|" \
                -e "s|%%PID_PATH%%|/application/nginx-1.10.1/logs/nginx.pid|" \
                -e "s|%%CONF_PATH%%|/application/nginx-1.10.1/conf/nginx.conf|" \
                -e "s|%%ERROR_LOG_PATH%%|/application/nginx-1.10.1/logs/error.log|" \
                < man/nginx.8 > objs/nginx.8
make[1]: Leaving directory `/home/oldboy/tools/nginx-1.10.1'
[root@oldboy nginx-1.10.1]# echo $?
0
test -d '/application/nginx-1.10.1/logs' \
                || mkdir -p '/application/nginx-1.10.1/logs'
make[1]: Leaving directory `/home/oldboy/tools/nginx-1.10.1'
[root@oldboy nginx-1.10.1]# echo $?
0
对于新手来说,在安装服务时,可以通过获取执行命令的返回值来确定命令的执行状态,
从而快速确定命令是否执行成功。不过,有经验的技术人员不需要获取返回值,通过命令
的最后过程输出就可以快速判断是否成功。 
范例4-12:通过获取“$?”的返回值确定网站备份是否正确。 
提示当对服务器的数据进行备份时,我们会在执行完关键命令,例如tar或cp后,通过获取返回值来判断命令是否
成功
,备份数据是否完整。

[root@oldboy ~]# cd /etc/
[root@oldboy etc]# tar zcf /opt/services.tar.gz ./services    #<==打包备份
[root@oldboy etc]# echo $?  #<==检查备份后的$?是否为0,如果为0则表示上一tar命令执行成功,工作中会写成Shell脚本。
0

范例4-13:通过脚本控制命令及脚本执行后的返回值。

[root@oldboy scripts]# cat test4.sh
[ $# -ne 2 ] && {              #<==若参数个数不等于2,
echo "must be two args."       #<==则输出提示。
exit 119                     #<==终止程序运行并以指定的119状态值退出程序,赋值给当前Shell的“$?”变量。
}
echo oldgirl
[root@oldboy scripts]# sh test4.sh #<==执行
脚本。
must be two args.
[root@oldboy scripts]# echo $?
119 #<==返回值为119,这个就是脚本中exit传过来的返回值。
[root@oldboy scripts]# sh test4.sh a1 a2 #<==若满足参数要求,
oldgirl #<==则跳过不合要求的提示及以119状态退出的两条命令。
[root@oldboy scripts]# echo $?
0 #<==返回值为0,这个就是echo oldgirl正确执行后,“$?”的结果。
在企业场景下,“$?”返回值的用法如下: 1)
判断命令、脚本或函数等程序是否执行成功。
 2)若在脚本中调用执行“exit数字”,则会返回这个数字给“$?”变量。 
3)如果是在函数里,则通过“return数字”把这个数字以函数返回值的形式传给“$?”。
 范例4-14:查看系统脚本的应用情况,脚本名为/etc/init.d/rpcbind。
这里利用sed打印/etc/init.d/rpcbind脚本的第50-73行
,然后分析脚本里“$?”的使用情况!
[root@oldboy scripts]# sed -n '63,73p' /etc/init.d/rpcbind
stop() {
        echo -n $"Stopping $prog: "
        killproc $prog  #<==这是停止rpcbind的命令。
        RETVAL=$? #<==将上述命令的返回值“$?”赋值给RETVAL变量,用于后面的判断。
        echo
        [ $RETVAL -eq 0 ]&&{ #<==这里就是判断,如果返回值为0,则执行下面的指令。
                rm -f /var/lock/subsys/$prog
                rm -f /var/run/rpcbind*
        }
        return $RETVAL  #<==如果返回值不等于0,则跳过条件表达式的判断,在这里直接作为返回值传给执行stop函数的脚本。
}
提示有关特殊位置和进程的状态变量,可以多参考这个简单却功能强大的脚本。 2.$$特殊变量功能及实践 范例4-15:获取脚本执行的进程号(PID)。
[root@oldboy scripts]# cat test_pid.sh  #<==编写一个简单的脚本。
echo $$ >/tmp/a.pid #<==获取$$的值,并重定向到/tmp/a.pid里。
sleep 300           #<==休息300秒,模拟守护进程不退出。
[root@oldboy scripts]# ps -ef|grep test_pid|grep -v grep
[root@oldboy scripts]# sh test_pid.sh & #<==在后台运行脚本,&符号表示在后台运行。
[1] 10397                               #<==这是脚本的进程号。
[root@oldboy scripts]# ps -ef|grep test_pid|grep -v grep
root     10397 10292  0 15:57 pts/0    00:00:00 sh test_pid.sh #<==这是脚本的进程号。
[root@oldboy scripts]# cat /tmp/a.pid
10397 #<==这是$$对应的值。


转载于:https://www.jianshu.com/p/d640ff3d1ff3

猜你喜欢

转载自blog.csdn.net/weixin_34153893/article/details/91326388