while ループに内部スコープがあるように見える理由を誰か説明してもらえませんか? オンラインで複数の説明を見ましたが、すべてパイプに関するものでした。私のコードにはパイプがありません。
コード:
#!/bin/sh
while read line
do
echo "File contents: $line"
echo
if [ 1=1 ]; then
test1=bob
fi
echo "While scope:"
echo " test1: $test1"
done < test.txt
if [ 1=1 ]; then
test2=test2;
fi
echo;
echo "Script scope: "
echo " test1: $test1"
echo " test2: $test2"
出力:
File contents: In the file
While scope:
test1: bob
Script scope:
test1:
test2: test2
答え1
Bourne シェルでは、複合コマンド (while
ループなど) をリダイレクトすると、その複合コマンドがサブシェルで実行されます。
Solaris 10 およびそれ以前のバージョン1/bin/sh
では、これは Bourne シェルなので使用しないでください。代わりに/usr/xpg4/bin/sh
またはを使用し/usr/bin/ksh
て POSIX を取得しますsh
。
何らかの理由で を使用する必要がある場合は/bin/sh
、代わりに次のようにして回避します。
compound-command < file
できるよ:
exec 3<&0 < file
compound-command
exec <&3 3<&-
あれは:
- fd 0 を fd 3 に複製して保存し、fd 0 をファイルにリダイレクトします。
- コマンドを実行する
- fd 3 に保存されたコピーから fd 0 を復元します。そして、不要になった fd 3 を閉じます。
1 . Solaris 11 以降では、Oracle は最終的に (ようやく) /bin/sh
POSIX シェルを作成したため、sh
他のほとんどの Unix と同様に動作します ( sh
POSIX で指定された言語を解釈しますが、 をベースとしているため、その拡張機能をサポートしますksh88
(他の Unix と同様に、 はsh
現在一般的に ksh88、pdksh、bash、yash、または拡張 ash に基づいています))。