Может ли кто-нибудь объяснить мне, почему мой цикл 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 0 из сохраненной копии на fd 3. И закройте fd 3, который больше не нужен.
1. В Solaris 11 и более поздних версиях Oracle в конце концов (наконец-то) создала /bin/sh
оболочку POSIX, поэтому теперь она ведет себя как sh
большинство других Unix-систем (она интерпретирует sh
язык, указанный в POSIX, хотя и поддерживает расширения поверх него, поскольку основана на ksh88
(как и другие Unix-системы, которые sh
теперь в основном основаны на ksh88, pdksh, bash, yash или улучшенном ash))