下記のようなシェルスクリプトで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


コメント