Переменная область действия в цикле while-read в Solaris

Переменная область действия в цикле while-read в Solaris

Может ли кто-нибудь объяснить мне, почему мой цикл 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 0 из сохраненной копии на fd 3. И закройте fd 3, который больше не нужен.

1. В Solaris 11 и более поздних версиях Oracle в конце концов (наконец-то) создала /bin/shоболочку POSIX, поэтому теперь она ведет себя как shбольшинство других Unix-систем (она интерпретирует shязык, указанный в POSIX, хотя и поддерживает расширения поверх него, поскольку основана на ksh88(как и другие Unix-системы, которые shтеперь в основном основаны на ksh88, pdksh, bash, yash или улучшенном ash))

Связанный контент