如何在条件下使用 bash 返回码?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17573312/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 23:56:08  来源:igfitidea点击:

How to use bash return code in conditional?

bashshellconditionalreturn-value

提问by Patryk

I have a small piece of code which checks IP address validity :

我有一小段代码可以检查 IP 地址的有效性:

function valid_ip()
{
    local  ip=
    local  stat=1

    if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
        OIFS=$IFS
        IFS='.'
        ip=($ip)
        IFS=$OIFS
        if [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
            && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]; then
            stat=1
        else
            stat=0
        fi
    fi
    return $stat
}

But I am having problems with its usage in bash conditionals. I have tried many techniques to test its return value but most of them fail on me.

但是我在 bash 条件中使用它时遇到了问题。我尝试了很多技术来测试它的返回值,但大多数都失败了。

if [[ !$(valid_ip $IP) ]]; then

if [[ $(valid_ip IP) -eq 1 ]]; then

etc. etc. Can anyone suggest what should I do here ?

等等等等 谁能建议我在这里做什么?

EDIT

编辑

Following your suggestions I have used something like :

按照您的建议,我使用了类似的东西:

  if valid_ip "$IP" ; then
      ... do stuff
  else
      perr "IP: \"$IP\" is not a valid IP address"
  fi

and I get errors like

我得到了类似的错误

IP: "10.9.205.228" is not a valid IP address

IP:“10.9.205.228”不是有效的 IP 地址

采纳答案by chepner

The return code is available in the special parameter $?after the command exits. Typically, you only need to use it when you want to save its value before running another command:

$?命令退出后,返回码在特殊参数中可用。通常,您只需要在运行另一个命令之前保存其值时才需要使用它:

valid_ip "$IP1"
status1=$?
valid_ip "$IP2"
if [ $status1 -eq 0 ] || [ $? -eq 0 ]; then

or if you need to distinguish between various non-zero statuses:

或者如果您需要区分各种非零状态:

valid_ip "$IP"
case $? in
    1) echo valid_IP failed because of foo ;;
    2) echo valid_IP failed because of bar ;;
    0) echo Success ;;
esac

Otherwise, you let the various operators check it implicitly:

否则,您可以让各种运算符隐式检查它:

if valid_ip "$IP"; then
    echo "OK"
fi

valid_IP "$IP" && echo "OK"


Here is a simple, idiomatic way of writing valid_ip:

这是一种简单、惯用的写作方式valid_ip

valid_ip () {
    local ip=
    [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]] && {
        IFS='.' read a b c d <<< "$ip"
        (( a < 255 && b < 255 && c < 255 && d << 255 ))
    }
}

There are two expressions, the [[...]]and the { ... }; the two are joined by &&. If the first fails, then valid_ipfails. If it suceeds, then the second expression (the compound statement) is evaluated. The readsplits the string into four variables, and each is tested separately inside the arithmetic expression. If all are true, then the ((...))succeeds, which means the &&list succeeds, which means that valid_ipsucceeds. No need to store or return explicit return codes.

有两个表达式,the[[...]]和 the { ... }; 两者由&&. 如果第一个失败,则valid_ip失败。如果成功,则计算第二个表达式(复合语句)。的read分割串入四个变量,并且每个算术表达式中单独测试。如果全部为真,则((...))成功,即表示&&列表成功,即表示valid_ip成功。无需存储或返回显式返回代码。

回答by choroba

No parentheses needed if the exit status is inspected:

如果检查退出状态,则不需要括号:

if valid_ip $IP ; then
    ...

Just call the function in the way you would call any other command.

只需按照调用任何其他命令的方式调用该函数即可。