Respondiendoesta preguntaDescubrí una diferencia muy divertida (y sutil) entre el comportamiento en bash
y zsh
:
En 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 puede ver, la ejecución del alias x
se lleva a cabo en un subshell y, por lo tanto, el directorio actual no cambia.
No en 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] %
aquí se cambia el directorio.
Parece que &
in bash
tiene una prioridad diferente que in zsh
--- quiero decir, el comando parece leerse como
(cd /tmp && echo A) &
en bash
y como
cd /tmp && (echo A &)
en zsh
. ¿Es esto correcto o la causa del diferente comportamiento es otra?
Respuesta1
Comportamiento diferente y documentado enzshmisc
Una lista es una secuencia de cero o más sublistas, en la que cada sublista termina con
;
,&
,&|
,&!
o una nueva línea. Opcionalmente, este terminador se puede omitir de la última sublista de la lista cuando la lista aparece como un comando complejo dentro de(...)
o{...}
. Cuando una sublista termina con;
una nueva línea, el shell espera a que termine antes de ejecutar la siguiente sublista. Si una sublista termina con&
,&|
o&!
, el shell ejecuta la última canalización en segundo plano y no espera a que finalice (tenga en cuenta la diferencia con otros shells que ejecutan la sublista completa en segundo plano). Una canalización en segundo plano devuelve un estado de cero.
Respuesta2
Enterrada zshmisc(1)
está la siguiente línea:
Si una sublista termina con un
&',
&|' o `&!', el shell ejecuta la última canalización en segundo plano,
Si bien no indica específicamente que las otras canalizaciones en la sublista se ejecutan en el shell actual, eso parece ser lo que implica, y el comportamiento que observa respalda esa interpretación. Por ejemplo:
$ echo $foo $bar
$ foo=3 && bar=5 && sleep 1 &
$ echo $foo $bar
3 5
también admite la noción de que las dos primeras canalizaciones se ejecutan en el shell actual, y solo la última canalización de la sublista realmente se ejecuta en segundo plano.