bash学习记录(三) bash中的退出码和测试(Test)

bash学习记录(三) bash退出码和测试

1. Bash退出码

  • 脚本的退出命令,类似C语言中的 return value ,可以供脚本的父进程调用。

  • 每条命令返回一条状态状态,命令执行成功返回0,执行失败返回非0状态码可以理解为一个错误码(error code)。

  • 最后的命令返回的状态或者 exit nnn(这里的nnn必须是1~255之间的整数)传递给shell。

exit nnn exit exit $? 或者。都可以,是bash Return value的方式。

  • 可以使用 来反转状态。

2. Bash中的test

每个编程语言都会有对一个情况下测试的功能,Bash也不例外,bash提供test命令,多种的括号操作,最终要的If/else结构语句来实现test功能。

测试结构体(Test Constructs)

  • 一个if/else结构体会测试一系列命令的返回值是否是0也就是命令是否执行成功。如果成功执行另外一系列操作。

  • bash使用 [ 来进行测试,但是在后来的版本里,bash引进了 [[ 来拓展test命令,bash把[[$a -lt $b]]看作一个元素,他会返回一个状态码(成功0,不成功是非0)

  • 当使用let(()) 的时候,对计算表达式进行运算的时候也会返回exit code,用于对算式的测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
(( 0 && 1 ))                 # Logical AND
echo $? # 1 ***
# And so ...
let "num = (( 0 && 1 ))"
echo $num # 0
# But ...
let "num = (( 0 && 1 ))"
echo $? # 1 ***


(( 200 || 11 )) # Logical OR
echo $? # 0 ***
# ...
let "num = (( 200 || 11 ))"
echo $num # 1
let "num = (( 200 || 11 ))"
echo $? # 0 ***


(( 200 | 11 )) # Bitwise OR
echo $? # 0 ***
# ...
let "num = (( 200 | 11 ))"
echo $num # 203
let "num = (( 200 | 11 ))"
echo $? # 0 ***

# The "let" construct returns the same exit status
#+ as the double-parentheses arithmetic expansion.
  • if可以测试任何条件 不仅仅是包在括号里面的条件。

  • Else if and elif

    elif相当与 else if,要请求分支需要用到elif

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    if [ condition1 ]
    then
    command1
    command2
    command3
    elif [ condition2 ]
    # Same as else if
    then
    command4
    command5
    else
    default-command
    fi
  • Equivalence of test, /usr/bin/test,[ ], and /usr/bin/[ 使用这几个做判断都是一样的。更复杂的表达式要使用[[]]来代替[]

    Using the [[ … ]] test construct, rather than [ … ] can prevent many logic errors in scripts. 这是Advanced Bash-Scripting Guide给出的建议。

文件测试操作(File)

  • -e 文件是否存在

  • -a 文件是否存在(以弃用)

  • -f 是否是普通文件(不是目录文件或者设备文件)

  • -s 是否是空文件

  • -d 是否是目录

  • -b 是否是块设备(block device)

  • -c 是否是字符设备(character device)

  • -h 是否是链接文件(symbolic link)

  • -S file is socket

  • -r -w -x 分别对应文件的 读写执行权限

  • -O 是否是文件的拥有者

  • -G group-id是否和你自己的相同

  • -N 在最后一次被读之后文件已经更改

  • f1 -nt f2 f1比f2新

  • -ot f1比f2旧

  • -ef f1和f2 引用同一个文件

  • 例子

    1
    2
    3
    4
    5
    6
    7
    8
    for directory in $directorys; do
    if [ -d $directory ]
    then linkchk $directory
    else
    echo "$directory is not a directory"
    echo "Usage: $0 dir1 dir2 ..."
    fi
    done

    其他比较操作(Integer,String)

整型和字符串类型使用两组不同的操作

整形

  • -eq 相等比较 if [ "$a" -eq "$b" ]

  • -ne 比较不相等 if [ "$a" -ne "$b" ]

  • -gt 大于等于(is greater than or equal to) if [ "$a" -ge "$b" ]

  • -lt 小于(is less than) if [ "$a" -lt "$b" ]

  • -le 小于等于(is less than or equal to) `if [ “$a” -le “$b” ]

  • < > <= >= 对应大于,小于,小于等于,大于等于这些相应的操作

String类型

  • = 判断字符串是否相等

  • == 和 = 相同,同样是判断字符串是否相同 但 == 在 [] 和 [[]] 中定义不同,下面举例:

1
2
3
4
5
[[ $a == z* ]]   # True if $a starts with an "z" (pattern matching).
[[ $a == "z*" ]] # True if $a is equal to z* (literal matching).

[ $a == z* ] # File globbing and word splitting take place.
[ "$a" == "z*" ] # True if $a is equal to z* (literal matching).
  • != 不等于

  • < and > 大于小于 按照ASCII 码比较

  • -z 空字符串,因此,字符串长度为0

  • -n 字符串不为空

逻辑比较

  • -a 表示逻辑与

  • -o 表示逻辑或

    -a -o 要使用在单个中括号中if [ "$expr1" -a "$expr2" ]

    && and || 但是要在双中括号中使用[[ condition1 && condition2 ]]

嵌套 if else

如其他编程语言类似,if else结构能够嵌套,但是嵌套结构和使用 && 比较符结果相同

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
a=3

if [ "$a" -gt 0 ]
then
if [ "$a" -lt 5 ]
then
echo "The value of \"a\" lies somewhere between 0 and 5."
fi
fi

# Same result as:

if [ "$a" -gt 0 ] && [ "$a" -lt 5 ]
then
echo "The value of \"a\" lies somewhere between 0 and 5."
fi
-------------本文结束感谢您的阅读-------------

本文标题:bash学习记录(三) bash中的退出码和测试(Test)

文章作者:NanYin

发布时间:2018年04月12日 - 15:04

最后更新:2019年08月12日 - 13:08

原始链接:https://nanyiniu.github.io/2018/04/12/2018-04-12-bash_exitCode/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。