
Bashに初めて触れ、ローカル/グローバル変数/サブシェルについて混乱しました。なぜ修正された変数が関数の終わりに印刷されないのかわかりません。ファイルの最後に最終行番号とファイル番号を印刷しようとしましたが、そうすると0だけが印刷されます。ローカル変数だからです。修正された値を出力する方法はありますか?
count=0
files=0
find . -type f | while IFC= read -r file;
do
let files=files+1
wc -l $file
count=$(($count+$(wc -l < $file)))
echo "total lines $count ; total files $files"
done
echo $files $count
exit 0
答え1
はい。しかし、これは確かに直感的ではありません。たとえば、次のように動作します。
#!/bin/bash
count=0
files=0
while IFS= read -r file;
do
let files=files+1
wc -l $file
count=$(($count+$(wc -l < $file)))
echo "total lines $count ; total files $files"
done < <(find . -type f )
echo "$files $count"
exit 0
この<(command)
構造は「プロセス置換」コマンドの出力を「ファイル」として表示できます。このようにループに入力すると、スクリプトが期待どおりに機能する可能性があります。
問題はパイプ(|
)を使用することです。これにより、while ループが別のサブシェルで実行され、外部変数を変更できなくなります。
この機能をサポートしていないシェルでは、サブシェル<()
のパイプの右側でコマンドを実行し、そのサブシェルに最終エコーを含めることができます。
#!/bin/bash
files=0
find . -type f | {
while IFC= read -r file;
do
let files=files+1
wc -l $file
count=$(($count+$(wc -l < $file)))
echo "total lines $count ; total files $files"
done
echo "$files $count"
}
exit 0