On Tue, 10 Apr 2001, Eliphas Levy Theodoro wrote:
> minha contribuiçãozinha em bash também...
>
> arq=ARQUIVO
> cat $arq | while read linha; do
> export IFS=,
> set - $linha
> script_em_perl "$2"
> script_em_bash "$1"
> done
>
> estou usando o IFS para dizer ao bash que o separador é a vírgula.
> não preciso guardar o IFS anterior e depois restaurar porque o próprio
> while tem o defeito (feature?) de não compartilhar as variáveis usadas por
> ele depois que ele se vai.
Não é defeito, é que o "|while" é considerado um novo processo, e
portanto ele tira uma cópia das variáveis de ambiente, e o |while
recebe essa cópia, com tudo o que o "processo" anterior tinha, mas não
"devolve" nada, pois um processo não é capaz de mudar as variáveis de
ambiente do "pai".
É necessário que o |while "aparente ser" uma outra task, para que se
mantenha a consistência de operação caso, em vez de "|while", se tenha
de fato um outro processo.
A única diferença entre o "|while" e um processo normal, é que o
"|while" vai receber todas as variáveis, mesmo as não exportadas,
enquanto um processo recebe apenas as variáveis exportadas.
Eu considero esse comportamente "estranho", já fiz vários scripts
esperando que um |while criasse e alterasse as variáveis, mas
infelizmente compreendo que é realmente necessário manter a
consistência de comportamento entre um pipe para uma task normal e um
pipe para um shell script "in-line".
O export do IFS neste caso é desnecessário pois IFS já é uma variável
exportada.
> a outra maneira seria guardar o IFS em uma variável antes do while,
> mudar ela para vírgula, e usar o próprio while para pegar os dois
> parâmetros. depois restaurando o IFS após o done. mas essa fica de
> lição de casa. ':)
Era o que eu recomendaria, mas eu tinha dúvidas com relação ao IFS.
Seu comentário me motivou a rever esse ponto obscuro (para mim) sobre
essa variável.
O que eu não sabia é que se o shell for iniciado ele redefine a
variável IFS para o default: espaco, TAB e newline.
O que vai acontecer dentro do |while é que os programas executados vão
receber "IFS=," mas se o programa for um shell script, então IFS será
redefinido.
Compilando e executando o programa C abaixo, com:
gcc -o x x.c
IFS=,;./x "$IFS"
percebe-se que o programa "./x" recebe a variável de ambiente IFS
alterada mas o system(), ao reiniciar um novo "sh", redefine esta
variável para o default.
Resta testar se com um "exec*" a variável é ou não redefinida. É
provável que não (a menos que seja um shell script ... :)
/* x.c: teste de IFS */
#include <stdio.h>
main(int argc, char *argv[]) {
int i;
for (i=1; i<argc; ++i)
printf ("%d: <%s>\n", i, argv[i]);
printf ("IFS para esse programa: <%s>\n", getenv ("IFS"));
system ("echo para um subshell: IFS=\\<$IFS\\>");
}
/* end of file */
Interessante rever esse comportamento da IFS. Não a usava pois temia
que problemas se propagassem de forma não controlada...
--- Wagner [EMAIL PROTECTED]
Assinantes em 11/04/2001: 2200
Mensagens recebidas desde 07/01/1999: 108747
Historico e [des]cadastramento: http://linux-br.conectiva.com.br
Assuntos administrativos e problemas com a lista:
mailto:[EMAIL PROTECTED]