Prof. Armando Luiz N. Delgado
Como visto na aula anterior, o comando interno read de bash(1) é usado para ler strings do teclado. A forma básica para read é:
read [-t timeout] [-p prompt] [-s] [var1] [var2] ...
onde:
Dos dados digitados, cada palavra é assinalada como valor de cada Variável de Ambiente especificada (i.e., var1, var2, etc.). Se não são fornecidas variáveis, o valor é assinalado à variável REPLY.
ci066@dupond:~$ read -p "Indique Nome, Idade e Endereco: " NOME IDADE END
Indique Nome, Idade e Endereco: Armando 18 Rua dos Alfeneiros, 25
ci066@dupond:~$ echo $NOME
Armando
ci066@dupond:~$ echo $IDADE
18
ci066@dupond:~$ echo $END
Rua dos Alfeneiros, 25
ci066@dupond:~$
Mais detalhes sobre o comando interno read podem ser vistos na seção SHELL BUILTIN COMMANDS do manual on-line de bash(1).
O comando read pode também ser também usado par ler de arquivos, redirecionando-se STDIN ou usando-se pipeline.
read FONE < fones.txt
OBS.: O uso de redirecionamento de STDIN com read não funciona em versões de UNIX anteriores a System V Release 2.
O exemplo acima lê apenas 1 (uma) linha do arquivo fones.txt. caso se queira ler várias linhas em seqüência e efetuar alguma operação sobre cada uma, o exemplo acima não funciona. A solução é mostrada abaixo:
cat fones.txt | while read ; do echo $REPLY done
Neste caso, o nome do arquivo de onde se lê está evidente no início do pipeline, evitando confusões.
NOTA: Pode-se alterar a solução acima para usar redirecionamento, embora não seja recomendado, pois o nome do arquivo fica pouco evidente no código do script:
while read ; do echo $REPLY done < fones.txt
Suponha o script varecho, que apenas mostre o valor de uma variável de ambiente x:
ci066@dupond:~$ cat varecho
echo ''VAR = :$x:''
ci066@dupond:~$ x=100
ci066@dupond:~$ varecho
VAR = ::
ci066@dupond:~$
Como se vê acima, varecho não conhecia o valor de x. Assim, seu valor na execução do script é nulo e nada é mostrado. Dizemos que a variável x que foi definida no shell de login é uma variável local. Da mesma forma, a variável x definida no script é local em relação à execução do script.
Outro exemplo:
ci066@dupond:~$ cat varecho2
x=50
echo ''VAR = :$x:''
ci066@dupond:~$ x=100
ci066@dupond:~$ varecho2
VAR = :50:
ci066@dupond:~$ echo ''$x''
100
ci066@dupond:~$
Note-se que o script varecho2 não mudou o valor de x no shell de login.
Este comportamento é devido ao fato que scripts shell são executados como subshells (processos diferentes). Toda vez que um subshell é iniciado, ele é executado em um ambiente totalmente novo, com seu próprio conjunto de variáveis de ambiente. Um subshell não tem conhecimento de variáveis locais que foram definidas pelo subshell pai (Figura 1).
Quando um script termina, o subshell também termina, juntamente com quaisquer variáveis definidas.
A forma usada para tornar o valor de uma variável conhecida a um subshell é exportando seu valor através do comando interno de bash(1), export:
z="Arnoldo" x=100 export x z export y=200
Observe o exemplo abaixo:
ci066@dupond:~$ cat varecho3
echo ''Y = :$y:''
echo ''X = :$x:''
ci066@dupond:~$ x=100
ci066@dupond:~$ y=10
ci066@dupond:~$ varecho3
Y = ::
X = ::
ci066@dupond:~$ export y
ci066@dupond:~$ varecho3
Y = :10:
X = ::
Sempre que um subshell é iniciado, uma cópia da lista de variáveis exportadas é passada ao subshell, enquanto a lista de variáveis locais não o é (Figura 2).
O que acontece se o subshell muda o valor de uma variável exportada? A mudança vai ser refletida no processo pai? A resposta à última pergunta é NÃO. Não há maneira de mudar o valor de uma variável em um shell pai a partir de um subshell:
ci066@dupond:~$ cat varecho4
x=50
y=5
ci066@dupond:~$ x=100
ci066@dupond:~$ y=10
ci066@dupond:~$ export y
ci066@dupond:~$ varecho4
ci066@dupond:~$ echo ''$x $y''
100 10
ci066@dupond:~$
A variável y criada em varecho4 não se confunde com a variável y exportada pelo shell de login (Figura 3).
Por outro lado, toda variável que é exportada, ele permanece exportada para todos os subshells subsequentes (Figura 4).
ci066@dupond:~$ cat varecho4
x=50
y=5
z=1
export z
varecho5
ci066@dupond:~$ cat varecho5
echo ''x = $x''
echo ''y = $y''
echo ''z = $z''
ci066@dupond:~$ x=100
ci066@dupond:~$ y=10
ci066@dupond:~$ export y
ci066@dupond:~$ varecho4
x =
y = 5
z = 1
ci066@dupond:~$
Finalmente, para que as mudanças em variáveis feitas em um script tenham efeito no shell (ou subshell) corrente, usa-se o comando interno de bash(1) . ou source.
ci066@dupond:~$ cat vars
LIVRO=''/home/prof/delga/livro''
DOCS=''/home/prof/delga/documentos''
CAL=''/home/prof/delga/calendar''
ci066@dupond:~$ vars
ci066@dupond:~$
ci066@dupond:~$ source vars
ci066@dupond:~$ echo $LIVRO
/home/prof/delga/livro
ci066@dupond:~$
case expressao in padrao_1a [ | padrao_1b ... ]) lista_1 ;; padrao_2a [ | padrao_2b ... ]) lista_2 ;; padrao_3a [ | padrao_3b ... ]) lista_3 ;; padrao_4a [ | padrao_4b ... ]) lista_4 ;; ... [ *) lista_default ;; ] esac case palavra in pattern [ | pattern ] ... ) lista ;; ] ... esacSe o valor da expressão for igual a padrão_1a OU padrão_1b, executa lista_1. Senão, se o valor da expressão for igual a padrão_2a OU padrão_2b, executa lista_2, e assim sucessivamente. O padrão * representa a execução default. É equivalente a um else. Após a execução de qualquer lista, o comando seguinte ao bloco case...esac é executado.
Exemplos podem ser encontrados no link de Exemplos na página HTML da disciplina.