Pierwszeństwo && vs & w bash i zsh

9

Odpowiadając na to pytanie odkryłem bardzo zabawne (i subtelne) różnicę między zachowaniem się bashi zsh:

W 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

Jak widać, wykonanie aliasu xodbywa się w podpowłoce, więc bieżący katalog się nie zmienia.

Nie w 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] % 

tutaj katalog się zmienia.

Wygląda na to, że &in bashma inny priorytet niż w zsh--- Mam na myśli, że polecenie wydaje się czytane jako

(cd /tmp && echo A) & 

w bashi jako

cd /tmp && (echo A &) 

w zsh. Czy to jest prawidłowe, czy przyczyną innego zachowania jest inne?

Rmano
źródło

Odpowiedzi:

9

Różne, udokumentowane zachowanie w zshmisc

Lista jest sekwencja zero lub więcej podlist, w którym każdy podlistę jest zakończony ;, &, &|, &!albo linią. Terminator można opcjonalnie pominąć w ostatniej liście podrzędnej na liście, gdy lista pojawia się jako złożone polecenie wewnątrz (...)lub {...}. Kiedy lista podrzędna zostanie zakończona przez ;lub nową linię, powłoka czeka na zakończenie przed wykonaniem kolejnej listy podrzędnej. Jeśli lista podrzędna jest zakończona przez a &, &|lub &!, powłoka wykonuje w niej ostatni potok w tle i nie czeka na zakończenie (zauważ różnicę od innych powłok wykonujących całą podlistę w tle). Potok w tle zwraca zero.

llua
źródło
3

Pochowany zshmisc(1)jest następujący wiersz:

Jeśli lista podrzędna jest zakończona znakiem &',& | lub `&! ', Powłoka wykonuje w niej ostatni potok w tle,

Chociaż nie określa konkretnie, że inne potoki na sublist są wykonywane w bieżącej powłoce, wydaje się, że to sugeruje, a obserwowane zachowanie potwierdza tę interpretację. Na przykład:

$ echo $foo $bar

$ foo=3 && bar=5 && sleep 1 &
$ echo $foo $bar
3 5

popiera również założenie, że pierwsze dwa potoki są wykonywane w bieżącej powłoce, a tylko ostatni potok podlisty jest wykonywany w tle.

chepner
źródło