116

echo最後のステートメントが空白である理由を説明してください。XCODEこれは、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ステートメントの外には出力されません。ここで変数スコープについて何かが欠けていると思いますが、古いマニュアルページにはそれが表示されていません。

4

7 に答える 7

140

whileループにパイプしているため、whileループを実行するためのサブシェルが作成されます。

これで、この子プロセスには環境の独自のコピーがあり、(他のUNIXプロセスと同様に)親に変数を戻すことはできません。

したがって、ループに配管されないように再構築する必要があります。または、たとえば関数で実行し、必要なecho値をサブプロセスから返すこともできます。

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

于 2008-09-23T22:29:16.607 に答える
120

問題は、パイプと一緒にまとめられたプロセスがサブシェルで実行されることです(したがって、独自の環境があります)。内で何が起こってwhileも、パイプの外には何の影響もありません。

あなたの特定の例は、パイプをに書き直すことによって解決することができます

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

多分

while ... do ... done < <(echo "$OUTPUT")
于 2008-09-23T22:37:40.080 に答える
10

これも同様に機能するはずです (echo と while は同じサブシェルにあるため):

#!/bin/bash
cat /tmp/randomFile | (while read line
do
    LINE="$LINE $line"
done && echo $LINE )
于 2014-11-27T16:24:09.820 に答える
2

もう 1 つのオプションは、結果をサブシェルからファイルに出力し、それを親シェルで読み取ることです。何かのようなもの

#!/bin/bash
EXPORTFILE=/tmp/exportfile${RANDOM}
cat /tmp/randomFile | while read line
do
    LINE="$LINE $line"
    echo $LINE > $EXPORTFILE
done
LINE=$(cat $EXPORTFILE)
于 2011-04-11T17:33:36.783 に答える
2
 #!/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

それらの変更が役立つかどうかを確認します

于 2008-09-23T22:03:29.100 に答える
1

私は自分の小さなデュを作っていたときにこれを回避しました:

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" )

ポイントは、SUM 変数と while を含む ( ) を含むサブシェルを作成することですが、while 自体ではなく ( ) 全体にパイプすることで問題を回避します。

于 2016-08-24T13:04:02.057 に答える