> 文章列表 > Shell的退出状态(if语句判断的是某个命令的退出状态)

Shell的退出状态(if语句判断的是某个命令的退出状态)

Shell的退出状态(if语句判断的是某个命令的退出状态)

以下内容源于C语言中文网的学习与整理,如有侵权,请告知删除。

一、退出状态

(1)不管是 Bash 内置命令,还是外部的 Linux 命令,还是自定义的 Shell 函数,当它运行结束或者退出时,都会返回一个比较小的整数值给调用它的程序,这个整数值就表示命令的退出状态。

很多 Linux 命令其实就是一个C语言程序,熟悉C语言的读者都知道,main() 函数的最后都有一个return 0,如果程序想在中间退出,还可以使用exit 0,这其实就是C语言程序的退出状态。当有其它程序调用这个程序时,就可以捕获这个退出状态。

(2)在 Shell 中,有多种方式取得命令的退出状态,其中 $?是最常见的一种。

xjh@ubuntu:~/iot/tmp$ cat test.sh 
#!/bin/bashread a
read b(( $a == $b ));echo "退出状态:"$?
xjh@ubuntu:~/iot/tmp$ ./test.sh 
33
33
退出状态:0
xjh@ubuntu:~/iot/tmp$ ./test.sh 
23
45
退出状态:1
xjh@ubuntu:~/iot/tmp$

(3)if 语句的判断条件,从本质上讲,判断的就是命令的退出状态。注意,Shell中退出状态为 0 表示“成功”、“真”,即程序执行完成并且没有遇到任何问题,除 0 以外的其它任何退出状态都为“失败”、“假”。注意,这正好与C语言的规定相反,在C语言中,0 表示“假”,其它值表示“真”。

如果shell中一个命令(比如判断大小)成立,则其返回值为0,而shell中的if也是命令返回值为0时才成立,这样一来,我们就可以只根据命令(比如大小关系)是否正确来判断if是否执行了,所谓“负负得正”,不用再绕弯子先去判断命令的返回值,然后再根据if只在返回值为0时才成立。比如下面代码中,直接看 $a是否等于$b即可。

xjh@ubuntu:~/iot/tmp$ cat test.sh 
#!/bin/bashread a
read bif (( $a == $b ))  # a=33,b=33时,由上面可知(( $a == $b ))退出的状态为0(表示成功、真) # 此时if根据退出的状态为真,then后面的内容得以执行# 或者直接看 $a是否等于$b即可。
thenecho "a和b相等"
fi
xjh@ubuntu:~/iot/tmp$ ./test.sh 
33
33
a和b相等
xjh@ubuntu:~/iot/tmp$

二、退出状态和逻辑运算符的组合 

(1)在if语句中,我们可以使用逻辑运算符将多个退出状态组合起来,一次判断多个条件。

Shell 逻辑运算符
运算符 使用格式 说明
&& if expression1 && expression2 逻辑与运算符,当 expression1 和 expression2 同时成立时,整个表达式才成立。

如果检测到 expression1 的退出状态为1(表示失败),就不会再检测 expression2 了,因为不管 expression2 的退出状态是什么,整个表达式必然都是不成立的,检测了也是多此一举。

|| if expression1 || expression2 逻辑或运算符,expression1 和 expression2 两个表达式中只要有一个成立,整个表达式就成立。

如果检测到 expression1 的退出状态为 0(表示成功),就不会再检测 expression2 了,因为不管 expression2 的退出状态是什么,整个表达式必然都是成立的,检测了也是多此一举。

! if !expression 逻辑非运算符,相当于“取反”的效果。如果 expression 成立,那么整个表达式就不成立;如果 expression 不成立,那么整个表达式就成立。

(2)举例:将用户输入的 URL 写入到文件中。下面代码中,test 是 Shell 内置命令,可以对文件或者字符串进行检测,其中,-w选项用来检测文件是否存在并且可写,-n选项用来检测字符串是否非空。>表示重定向,默认情况下,echo 向控制台输出,这里我们将输出结果重定向到文件。

xjh@ubuntu:~/iot/tmp$ cat test.sh 
#!/bin/bashread filename
read urlif test -w $filename && test -n $url
thenecho $url > $filenameecho "写入成功"
elseecho "写入失败"
fi
xjh@ubuntu:~/iot/tmp$ ./test.sh 
test.txt
http://www.baidu.com.cn
写入失败
xjh@ubuntu:~/iot/tmp$ touch test.txt
xjh@ubuntu:~/iot/tmp$ ls
test1.sh  test2.sh  test.sh  test.txt
xjh@ubuntu:~/iot/tmp$ ./test.sh 
test.txt
http://www.baidu.com.cn
写入成功
xjh@ubuntu:~/iot/tmp$
xjh@ubuntu:~/iot/tmp$ test -w test.txt
xjh@ubuntu:~/iot/tmp$ echo $?
0
xjh@ubuntu:~/iot/tmp$ test -w test.c
xjh@ubuntu:~/iot/tmp$ echo $?
1
xjh@ubuntu:~/iot/tmp$