Escopo variável em while-read-loop no Solaris

4

Alguém poderia me explicar por que meu loop while parece ter um escopo interno? Eu vi várias explicações online, mas todas elas têm a ver com tubos. Meu código não tem nenhum.

O código:

#!/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"

A saída:

File contents: In the file

While scope:
  test1: bob

Script scope:
  test1: 
  test2: test2
    
por Joel Cochran 17.06.2014 / 22:15

1 resposta

5

No Bourne shell, o redirecionamento de um comando composto (como o while loop) executa esse comando composto em um subshell.

No Solaris 10 e anterior 1 , você não deseja usar /bin/sh como o shell Bourne. Use /usr/xpg4/bin/sh ou /usr/bin/ksh para obter um POSIX sh .

Se por algum motivo você tiver que usar /bin/sh , então, para contornar isso, em vez de fazer:

compound-command < file

Você pode fazer:

exec 3<&0 < file
compound-command
exec <&3 3<&-

Isto é:

  1. duplique o fd 0 para o fd 3 para salvá-lo e, em seguida, redirecione fd 0 para o arquivo.
  2. execute o comando
  3. restaure o fd 0 da cópia salva no fd 3. E feche o fd 3, que não é mais necessário.

1 No Solaris 11 e posterior, o Oracle eventualmente (finalmente) fez /bin/sh um shell POSIX, então ele agora se comporta como sh da maioria dos outros Unices (ele interpreta a linguagem sh especificada pelo POSIX embora suporte extensões sobre como ele é baseado em ksh88 (como outros Unices, onde sh agora é geralmente baseado em ksh88, pdksh, bash, yash ou uma cinza aprimorada))

    
por 17.06.2014 / 22:58