シェルスクリプトでwhile文で使用した変数がループ外で反映されない場合
下記のようなシェルスクリプトでwhileループ内読み込んだファイルの内容を表示して、行数をカウントしています。
while内では、変数が表示されますがwhileループの外だと変数は「0」と表示されます
#!/bin/bash FILE=/var/tmp/file.txt CNT=0 cat $FILE | while read line; do CNT=`expr ${CNT} + 1` echo $line done echo "CNT:$CNT"
出力結果
$ cat /var/tmp/file.txt apricot melon peach apple grape $ sh test.sh apricot melon peach apple grape CNT:0
上記のスクリプトでは、ループ内で実行される変数が「0」となっています。これは、whileループがサブシェル内で実行されるためです。
whileループの処理を実行する際に、パイプ演算子( |
)を使用してパイプで繋がれたコマンドに対して入力しているので、whileループはサブシェルで実行されているので、ループ内で宣言された変数や変更が、ループ外のスコープには影響を与えないので「0」となります。
whileループ内の変数をループ外で使用したい場合は、リダイレクト(<) を使用してファイルを読み込めば、ループはサブシェルではなく、実行中のシェル内で直接実行されます。
【修正後のシェルスクリプト】
$ vi test.sh #!/bin/bash FILE=/var/tmp/file.txt CNT=0 while read -r line; do CNT=`expr ${CNT} + 1` echo $line done < "$FILE" echo "CNT:$CNT" # 実行結果 $ sh test.sh apricot melon peach apple grape CNT:5
ディスカッション
コメント一覧
まだ、コメントがありません