Bashvariables作用域

请向我解释为什么最后的“回声”声明是空白的? 我期望它在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 

我试过使用下面的语句而不是++ XCODE方法

 XCODE=`expr $XCODE + 1` 

它也不会在while语句之外打印。 我想我在这里错过了一些关于variables范围的东西,但是“手册”页面并没有显示给我。

因为你正在pipe道进入while循环,所以创build一个子shell来运行while循环。 现在这个subprocess拥有它自己的环境副本,不能将任何variables传回给它的父进程(就像在任何unix进程中一样)。

因此,您需要重新组织,以免导致进入循环。 或者,你可以运行一个函数,例如回显你想要从subprocess返回的值。

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

问题是与pipe道放在一起的过程是在子壳中执行的(因此有自己的环境)。 无论什么时候发生什么都不会影响pipe道外的任何事情。

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

 while ... do ... done <<< "$OUTPUT" 

也许

 while ... do ... done < <(echo "$OUTPUT") 

这也应该工作(因为回声和while在同一个子shell):

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

还有一个select:

 #!/bin/bash cat /some/file | while read line do var="abc" echo $var | xsel -i -p # redirect stdin to the X primary selection done var=$(xsel -o -p) # redirect back to stdout echo $var 

编辑:在这里,xsel是一个要求(安装它)。 或者,您可以使用xclip: xclip -i -selection clipboard代替xsel -i -p

  #!/bin/bash OUTPUT="name1 ip ip status" +export XCODE=0; if [ -z "$OUTPUT" ] ---- echo "CRIT: $NAME - $STATUS" - echo $((++XCODE)) + export XCODE=$(( $XCODE + 1 )) else echo $XCODE 

看看这些变化是否有帮助

另一种select是将结果输出到子shell中的文件中,然后在父shell中读取它。 就像是

 #!/bin/bash EXPORTFILE=/tmp/exportfile${RANDOM} cat /tmp/randomFile | while read line do LINE="$LINE $line" echo $LINE > $EXPORTFILE done LINE=$(cat $EXPORTFILE) 

当我做自己的小杜时,我解决了这个问题:

 ls -l | sed '/total/d ; s/ */\t/g' | cut -f 5 | ( SUM=0; while read SIZE; do SUM=$(($SUM+$SIZE)); done; echo "$(($SUM/1024/1024/1024))GB" ) 

重点是我用()包含我的SUMvariables和while来创build一个子shell,但是我把它变成了整个()而不是它本身,这避免了陷阱。