有人可以向我解释一下为什么我的 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 shell 中,重定向复合命令(如循环while
)会在子 shell 中运行该复合命令。
在 Solaris 10 及更早版本1中,您不想使用它,/bin/sh
因为它是 Bourne shell。使用/usr/xpg4/bin/sh
or/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 shell,因此它现在的行为与sh
大多数其他 Unices 类似(它解释sh
POSIX 指定的语言,尽管它支持对其进行扩展,因为它基于ksh88
(与其他 Unices 一样) ,sh
现在通常基于 ksh88、pdksh、bash、yash 或增强的 ash))