Solaris の while-read-loop における変数のスコープ

Solaris の while-read-loop における変数のスコープ

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<&-

あれは:

  1. fd 0 を fd 3 に複製して保存し、fd 0 をファイルにリダイレクトします。
  2. コマンドを実行する
  3. fd 3 に保存されたコピーから fd 0 を復元します。そして、不要になった fd 3 を閉じます。

1 . Solaris 11 以降では、Oracle は最終的に (ようやく) /bin/shPOSIX シェルを作成したため、sh他のほとんどの Unix と同様に動作します ( shPOSIX で指定された言語を解釈しますが、 をベースとしているため、その拡張機能をサポートしますksh88(他の Unix と同様に、 はsh現在一般的に ksh88、pdksh、bash、yash、または拡張 ash に基づいています))。

関連情報