Re: Algué m me explica...

"Fernando M. Roxo da Motta" <[email protected]>
Newsgroups gmane.org.user-groups.linux.parana
Message-ID <[email protected]>
  Putz !!   Fantástica demonstração do significado do escopo de uma
variável e/ou processo !!!!     Muito bom !

On Fri, Oct 14, 2005 at 02:37:04PM -0300, Matias Schweizer wrote:
> 	
> 	Pessoal:
> 
> 	Faz tempo que não caio em pegadinha de shell...Alguém explica
> 	pq o echo $X ao final das sequências é diferente?
> 
> 1-----------------------------------------------------------------------
> sor@plutao:~$ X=1
> sor@plutao:~$ while [ $X -lt 18 ];do X=`expr $X + 1`;echo $X;done

  Neste caso você diz para a SHELL interpretar/executar uma série de
comandos, na verdade um laço, *no mesmo* escopo do comando "X=1".

=========================8<----------------------------------
> 18
> sor@plutao:~$ echo $X
> 18
> 
> 2 ------------------------------------------------------------------------
> sor@plutao:~$ X=1
> sor@plutao:~$ cat /etc/passwd|while read line
> > do 
> > X=`expr $X + 1`
> > echo $X
> > done 

   Neste caso você diz para a SHELL executar um conjunto de comandos, mas
não no mesmo escopo do comando "X=1".


   Não ?   Como não ?!   Afinal foi no mesmo terminal !!

   Perfeito !  Mas o comando 'cat /etc/passwd' não pode ser exeecutado
neste escopo, por este motivo a SHELL vai ter que executar um "fork/exec"
para executar este binário (/bin/cat).   Além disto você tem uma
canalização (me amarro no português castiço ;)), ou "pipe" se preferir, o
que é uma outra chamada do sistema que executa um "fork/exec".    Portanto
o laço "while" será interpretado não no mesmo escopo do 'X=1' mas em uma
"subshell".   Como os processos pais não herdam as alteração no ambiente
dos processos filhos, as alterações nestes últimos são perdidas.


> 17
> 18
> sor@plutao:~$ echo $X
> 1
> 
> ???????
> 


  Logo, concluímos que não há como fazer o que você quer, certo ?

  Bem, na verdade não.   Basta você fazer com que o laço seja
executado/interpretado na mesma instância do primeiro comando.

  Como fazer isto ?

  Provavelmente existirão várias maneiras, mas uma delas seria :

$ X=1
$ for i in `cat /etc/passwd`
> do 
> X=`expr $X + 1`
> echo $X
> done
2
......   cortei o excesso de tráfego. ;))
17
18
$ echo $X
18


  Veja que neste caso também será executado o "fork/exec" para executar o
binário '/bin/cat', mas desta vez a saída será capturada *neste escopo* da
SHELL, portanto as alterações não mais estarão no processo filho, mas no
próprio processo pai.


  HTH.


  Roxo

--
---------------- Non luctari, ludare -------------------+ WYSIWYG Editor ?
Fernando M. Roxo da Motta <[email protected]>               |  VI !!
Except where explicitly stated I speak on my own behalf.| I see text,
      ( Usuário Linux registrado #39505 )               | I get text !
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.