• Bash脚本中的 set -euxo pipefail


    本文将介绍Bash中 set -euxo pipefail,它们可以帮助你写出更容易维护也更安全的脚本。这也是Bash脚本的终极调试手段。

    set -e

    set -e 选项可以让你的脚本在出现异常时马上退出,后续命令不再执行。默认情况下Shell脚本不会因为错误而结束执行,但大多数情况是,我们希望出现异常时就不要再往下走了。假如你的if判断条件里会出现异常,这时脚本也会直接退出,但可能这并不是你期望的情况,这时你可以在判断语句后加上 || true 来阻止退出。

    Before

    #!/bin/bash
    
    # 'foo' is a non-existing command
    foo
    echo "bar"
    
    # output
    # ------
    # line 4: foo: command not found
    # bar
    

    After

    #!/bin/bash
    set -e
    
    # 'foo' is a non-existing command
    foo
    echo "bar"
    
    # output
    # ------
    # line 5: foo: command not found
    

    阻止立即退出的例子。

    #!/bin/bash
    set -e
    
    # 'foo' is a non-existing command
    foo || true
    echo "bar"
    
    # output
    # ------
    # line 5: foo: command not found
    # bar
    

    set -o pipefail

    默认情况下Bash只会检查管道(pipeline)操作最后一个命令的返回值,假如最右边的命令成功那么它就认为这个语句没问题。这个行为其实是很不安全的,所以就有了set -o pipefail。这个特别的选项表示在管道连接的命令中,只要有任何一个命令失败(返回值非0),则整个管道操作被视为失败。只有管道中所有命令都成功执行了这个管道才算成功执行。

    Before

    #!/bin/bash
    set -e
    
    # 'foo' is a non-existing command
    foo | echo "a"
    echo "bar"
    
    # output
    # ------
    # a
    # line 5: foo: command not found
    # bar
    

    After

    #!/bin/bash
    set -eo pipefail
    
    # 'foo' is a non-existing command
    foo | echo "a"
    echo "bar"
    
    # output
    # ------
    # a
    # line 5: foo: command not found
    

    set -u

    set -u 比较容易理解,Bash会把所有未定义的变量视为错误。默认情况下Bash会将未定义的变量视为空,不会报错,这也是很多坑的来源。也许由于变量名的细微差别让你查半天最后骂骂咧咧。

    Before

    #!/bin/bash
    set -eo pipefail
    
    echo $a
    echo "bar"
    
    # output
    # ------
    #
    # bar
    

    After

    #!/bin/bash
    set -euo pipefail
    
    echo $a
    echo "bar"
    
    # output
    # ------
    # line 5: a: unbound variable
    

    set -x

    set -x 可以让Bash把每个命令在执行前先打印出来,你可以认为这就是Bash的Debug开关。它的好处当然显而易见,方便你快速找到有问题的脚本位置,但是也坏处也有吧,就是Bash的log会格外的乱。另外,它在打印命令前会把变量先解析出来,所以你可以知道当前执行的语句的变量值是什么。纵然log可能会乱一些,总比头发乱一些好,所以建议还是打开这个开关。

    #!/bin/bash
    set -euxo pipefail
    
    a=5
    echo $a
    echo "bar"
    
    # output
    # ------
    # + a=5
    # + echo 5
    # 5
    # + echo bar
    # bar


  • 相关阅读:
    BZOJ2697 特技飞行 【贪心】
    BZOJ2795/2890/3647 [Poi2012]A Horrible Poem 【字符串hash】
    BZOJ2823 [AHOI2012]信号塔 【最小圆覆盖】
    BZOJ2924 [Poi1998]Flat broken lines 【Dilworth定理 + 树状数组】
    洛谷P3759 [TJOI2017]不勤劳的图书管理员 【树状数组套主席树】
    POJ 2955
    江南大学第三届程序设计竞赛K题
    Codeforces 894C
    Codeforces 894B
    HDU 1789
  • 原文地址:https://www.cnblogs.com/wjoyxt/p/14734502.html
Copyright © 2020-2023  润新知