在bash中添加(收集)退出代码

时间:2009-06-16 09:14:28

标签: bash scripting shell exit-code

我需要在脚本中依赖几个单独的执行,并且不希望将它们全部捆绑在一个丑陋的'if'语句中。我想把退出代码'$?'每次执行并添加它;最后,如果这个值超过一个阈值 - 我想执行一个命令。

伪代码:

ALLOWEDERROR=5

run_something
RESULT=$?
..other things..

run_something_else
RESULT=$RESULT + $?

if [ $RESULT -gt ALLOWEDERROR ] 
   then echo "Too many errors"
fi

问题:即使互联网声称不然,bash拒绝对待RESULT和$?作为整数。什么是正确的语法?

感谢。

7 个答案:

答案 0 :(得分:14)

快速实验并深入了解bash信息:

declare -i RESULT=$RESULT + $?

因为您要多次添加结果,所以可以在开头使用declare,如下所示:

declare -i RESULT=0

true
RESULT+=$?
false
RESULT+=$?
false
RESULT+=$?

echo $RESULT
2

看起来更干净。

declare -i表示变量是整数。

或者,您可以避免声明并使用算术表达式括号:

RESULT=$(($RESULT+$?))

答案 1 :(得分:9)

您可能需要查看trap内置内容,看看它是否有用:

help trap

man bash

你可以为这样的错误设置一个陷阱:

#!/bin/bash

AllowedError=5

SomeErrorHandler () {
    (( errcount++ ))       # or (( errcount += $? ))
    if  (( errcount > $AllowedError ))
    then
        echo "Too many errors"
        exit $errcount
    fi
}

trap SomeErrorHandler ERR

for i in {1..6}
do
    false
    echo "Reached $i"     # "Reached 6" is never printed
done

echo "completed"          # this is never printed

如果您计算错误(并且仅在错误时),而不是使用“$?”,那么您不必担心返回值不是零或一。例如,单个返回值127会立即超过您的阈值。除了trap之外,您还可以为其他信号注册ERR

答案 2 :(得分:1)

使用$(( ... ))构造。

$ cat st.sh
RESULT=0
true
RESULT=$(($RESULT + $?))
false
RESULT=$(($RESULT + $?))
false
RESULT=$(($RESULT + $?))
echo $RESULT
$ sh st.sh
2
$

答案 3 :(得分:1)

以下是一些在bash或sh中执行添加的方法:

RESULT=`expr $RESULT + $?`
RESULT=`dc -e "$RESULT $? + pq"`

其他一些人只在bash中使用:

RESULT=$((RESULT + $?))
RESULT=`bc <<< "$RESULT + $?"` 

无论如何,错误时的退出状态并不总是1,其值不依赖于错误级别,因此在一般情况下,根据阈值检查状态总和没有多大意义。

答案 4 :(得分:1)

关于如何在Bash中添加数字,请参阅:

help let 

答案 5 :(得分:1)

如果您想在脚本中使用ALLOWEDERROR,请在前面加上$,例如$ ALLOWEDERROR。

答案 6 :(得分:-1)

正如mouviciel所说,收集返回代码的总和看起来相当无意义。也许,您可以使用数组来累积非零结果代码并检查其长度。这种方法的例子如下:

#!/bin/sh

declare RESULT
declare index=0
declare ALLOWED_ERROR=1

function write_result {
    if [ $1 -gt 0 ]; then
        RESULT[index++]=$1
    fi
}

true
write_result $?

false
write_result $?

false
write_result $?

echo ${#RESULT[*]}
if [ ${#RESULT[*]} -gt $ALLOWEDERROR ] 
   then echo "Too many errors"
fi