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]

Responder a