Bash变量范围

Mat*_*t P 102 bash scope pipe

请解释为什么最后一个"回声"声明是空白的?我希望它在while循环中增加到值1:

#!/bin/bash
OUTPUT="name1 ip ip status" # normally output of another command with multi line output

if [ -z "$OUTPUT" ]
then
        echo "Status WARN: No messages from SMcli"
        exit $STATE_WARNING
else
        echo "$OUTPUT"|while read NAME IP1 IP2 STATUS
        do
                if [ "$STATUS" != "Optimal" ]
                then
                        echo "CRIT: $NAME - $STATUS"
                        echo $((++XCODE))
                else
                        echo "OK: $NAME - $STATUS"
                fi
        done
fi

echo $XCODE
Run Code Online (Sandbox Code Playgroud)

我尝试使用以下语句而不是++ XCODE方法

XCODE=`expr $XCODE + 1`
Run Code Online (Sandbox Code Playgroud)

它也不会在while语句之外打印.我想我在这里缺少一些关于变量范围的东西,但是ol'手册页并没有显示给我.

pix*_*eat 111

因为您正在使用while循环,所以会创建一个子shell来运行while循环.现在这个子进程拥有它自己的环境副本,并且无法将任何变量传递回其父进程(如在任何unix进程中).

因此,您需要进行重组,以便不会进入循环.或者,您可以在函数中运行,例如,并回显您希望从子流程返回的值.

http://tldp.org/LDP/abs/html/subshel​​ls.html#SUBSHELL

  • 这只是回答了我在使用 bash 脚本编写时遇到的许多看似随机的问题。 (3认同)

mwe*_*den 104

问题是与管道放在一起的流程在子壳中执行(因此具有自己的环境).无论发生什么while都不会影响管道外的任何东西.

您可以通过重写管道来解决您的具体示例

while ... do ... done <<< "$OUTPUT"
Run Code Online (Sandbox Code Playgroud)

也许

while ... do ... done < <(echo "$OUTPUT")
Run Code Online (Sandbox Code Playgroud)

  • 对于那些正在考虑整个<()语法是什么的人(就像我一样),它被称为"过程替换",上面详述的具体用法可以在这里看到:http://mywiki.wooledge .ORG/ProcessSubstitution (31认同)
  • 每个人都应该定期使用过程替换!这是超级有用的。我每天都做类似`vimdiff &lt;(grep WARN log.1 | sort | uniq)&lt;(grep WARN log.2 | sort | uniq)`的事情。考虑到您可以一次使用多个文件,并将它们像文件一样对待...可能性! (2认同)

小智 8

这应该也可以(因为echo和while在同一个子shell中):

#!/bin/bash
cat /tmp/randomFile | (while read line
do
    LINE="$LINE $line"
done && echo $LINE )
Run Code Online (Sandbox Code Playgroud)