Solaris 上 while-read-loop 中的变量范围

Joe*_*ran 4 solaris shell-script variable bourne-shell

有人可以向我解释为什么我的 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"
Run Code Online (Sandbox Code Playgroud)

输出:

File contents: In the file

While scope:
  test1: bob

Script scope:
  test1: 
  test2: test2
Run Code Online (Sandbox Code Playgroud)

Sté*_*las 5

在 Bourne shell 中,重定向复合命令(如while循环)在子 shell 中运行该复合命令。

在 Solaris 10 和更早的1 中,您不想使用/bin/sh它,因为它是 Bourne shell。使用/usr/xpg4/bin/sh/usr/bin/ksh来获取 POSIX sh

如果由于某种原因您必须使用/bin/sh,然后解决这个问题,而不是执行以下操作:

compound-command < file
Run Code Online (Sandbox Code Playgroud)

你可以做:

exec 3<&0 < file
compound-command
exec <&3 3<&-
Run Code Online (Sandbox Code Playgroud)

那是:

  1. 将 fd 0 复制到 fd 3 以将其保存,然后将 fd 0 重定向到文件。
  2. 运行命令
  3. 从 fd 3 上保存的副本中恢复 fd 0。并关闭不再需要的 fd 3。

1 . 在 Solaris 11 及更高版本中,Oracle 最终(终于)制作/bin/sh了一个 POSIX shell,因此它现在的行为类似于sh大多数其他 Unices(它解释shPOSIX 指定的语言,尽管它支持基于它的扩展ksh88(如其他 Unices ,sh现在一般基于 ksh88、pdksh、bash、yash 或增强的 ash))