当while / if / etc有错误时,如何使bash脚本失败?

时间:2019-07-04 10:43:49

标签: linux bash shell jenkins groovy

我在Groovy上进行了詹金斯管道工作。 Groovy为每个步骤调用bash脚本。

当某种方式出现错误时,我想使整个工作失败。

对于Groovy,我使用returnStatus: true

对于Bash,我使用set -e

但是,例如,如果set -e语句有错误,带有while的bash脚本不会退出。根据“ set”的Linux手册页,这实际上应该发生。 我想知道在这种情况下如何立即退出。

脚本:

[jenkins-user@jenkins ~]$ cat script.sh
#!/bin/bash

set -xe

FILE=commands.txt

echo "echos before while"

# Run the commands in the commands file
while read COMMAND
do
    $COMMAND
done < $FILE
echo $?

echo "echos after faulty while"

比方说'commands.txt'不存在。 运行脚本:

[jenkins-user@jenkins ~]$ sh script.sh
echos before while
script.sh: line 13: commands.txt: No such file or directory
1
echos after faulty while
[jenkins-user@jenkins ~]$ echo $?
0

尽管while语句返回退出代码1,但该脚本继续执行并成功结束,如后所述,使用echo $?

这是我强制Groovy失败的方法,使用bash / python / etc命令/脚本执行的步骤返回了非零退出代码:

pipeline {
    agent any
    stages {
        stage("A") {
            steps {
                script {
                    def rc = sh(script: "sh A.sh", returnStatus: true)
                    if (rc != 0)  {
                        error "Failed, exiting now..."
                    }
                }
            }
        }
    }
}

第一个问题,当while / if / etc语句出错时,如何使SHELL脚本失败?我知道我可以使用command || exit 1,但是如果我在脚本中有数十条这样的语句,这看起来并不好。

第二个问题,我的Groovy错误处理正确吗?谁能建议一个更好的活动方法?也许有一个Jenkins插件/官方方法可以做到这一点?

4 个答案:

答案 0 :(得分:1)

第一个问题,该链接可能有帮助Aborting a shell script if any command returns a non-zero value

第二个问题:您可以使用try和catch进行异常处理来改善错误处理。

 try{
       def rc = sh(script: "sh A.sh", returnStatus: true)
       if (rc != 0)  {
                error "Failed, exiting now..."
       }
    }  
    catch (Exception er){
         errorMessage = er.getMessage();
    }

答案 1 :(得分:0)

为什么不只使用while退出代码并返回它呢? (请参阅脚本的此修改版本,最后几行)

[jenkins-user@jenkins ~]$ cat script.sh
#!/bin/bash

set -xe

FILE=commands.txt

echo "echos before while"

# Run the commands in the commands file
while read COMMAND
do
    $COMMAND
done < $FILE
status=$?

echo "echos after faulty while"

exit $status

答案 2 :(得分:0)

[jenkins-user@jenkins ~]$ cat script.sh
#!/bin/bash

set -xe

FILE=commands.txt

echo "echos before while"

# Run the commands in the commands file
while read COMMAND
do
    $COMMAND
done < $FILE
echo $?

echo "echos after faulty while"

当您在此脚本之后执行echo $?时,它将始终为0,因为最后一个命令为echo "echos after faulty while",因此您可以在脚本结尾处添加一个exit 1。在exit 1中,数字1为错误代码,您可以使用other。因此脚本将是

[jenkins-user@jenkins ~]$ cat script.sh
#!/bin/bash

set -xe

FILE=commands.txt

echo "echos before while"

# Run the commands in the commands file
while read COMMAND
do
    $COMMAND
done < $FILE
echo $?
exit 1

答案 3 :(得分:0)

关于Bash脚本。

您的问题是,即使使用了set -e,失败重定向也不会终止bash脚本。我很惊讶自己。但这是我对set -e的第一次失望,所以现在我考虑不信任它,我滥用了$command || exit 1 ...

在这里您可以执行以下操作:

set -xe -o pipefail
cat $FILE | while read command; do $command ; done

但是整个循环应该简化为:

bash $FILE