Respondendoessa questãoEu descobri uma diferença muito engraçada (e sutil) entre comportamento em bash
e zsh
:
Em bash
:
romano@RRyS:~$ pwd
/home/romano
romano@RRyS:~$ alias x="cd /bin && ./echo A >/dev/null &"
romano@RRyS:~$ x
[1] 16611
romano@RRyS:~$ pwd
/home/romano
Como você pode ver, a execução do alias x
é realizada em um subshell e portanto o diretório atual não muda.
Não em zsh
:
[romano:~] % pwd
/home/romano
[romano:~] % alias x="cd /bin && ./echo A >/dev/null &"
[romano:~] % x
[1] 16744
[1] + 16744 done ./echo A >/dev/null
1& [romano:/bin] % pwd
/bin
[romano:/bin] %
aqui o diretório é alterado.
Parece que &
in bash
tem uma prioridade diferente de in zsh
--- quero dizer, o comando parece ser lido como
(cd /tmp && echo A) &
em bash
e como
cd /tmp && (echo A &)
em zsh
. Isso está correto ou a causa do comportamento diferente é outra?
Responder1
Comportamento diferente e documentado emzshmisc
Uma lista é uma sequência de zero ou mais sublistas, em que cada sublista é terminada por
;
,&
,&|
,&!
ou uma nova linha. Este terminador pode opcionalmente ser omitido da última sublista da lista quando a lista aparece como um comando complexo dentro de(...)
ou{...}
. Quando uma sublista é encerrada por;
ou nova linha, o shell espera que ela termine antes de executar a próxima sublista. Se uma sublista for finalizada por&
,&|
, ou&!
, o shell executa o último pipeline nela em segundo plano e não espera que ele termine (observe a diferença de outros shells que executam toda a sublista em segundo plano). Um pipeline em segundo plano retorna um status zero.
Responder2
Enterrada zshmisc(1)
está a seguinte linha:
Se uma sublista for finalizada por um
&',
&|' ou `&!', o shell executa o último pipeline em segundo plano,
Embora não afirme especificamente que os outros pipelines na sublista são executados no shell atual, isso parece ser o que está implicando, e o comportamento que você observa apoia essa interpretação. Por exemplo:
$ echo $foo $bar
$ foo=3 && bar=5 && sleep 1 &
$ echo $foo $bar
3 5
também suporta a noção de que os dois primeiros pipelines são executados no shell atual e apenas o último pipeline da sublista é realmente executado em segundo plano.