Zgodnie z tym , umieszczenie listy poleceń między nawiasami klamrowymi powoduje, że lista jest wykonywana w bieżącym kontekście powłoki. Nie jest tworzona podpowłoka .
Za pomocą, ps
aby zobaczyć to w akcji
Jest to hierarchia procesów dla potoku procesu wykonywanego bezpośrednio w wierszu poleceń. 4398 to PID dla powłoki logowania:
sleep 2 | ps -H;
PID TTY TIME CMD
4398 pts/23 00:00:00 bash
29696 pts/23 00:00:00 sleep
29697 pts/23 00:00:00 ps
Teraz postępuje zgodnie z hierarchią procesu dla potoku procesu między nawiasami klamrowymi wykonywanymi bezpośrednio w wierszu poleceń. 4398 to PID dla powłoki logowania. Jest to podobne do powyższej hierarchii udowadniającej, że wszystko jest wykonywane w bieżącym kontekście powłoki :
{ sleep 2 | ps -H; }
PID TTY TIME CMD
4398 pts/23 00:00:00 bash
29588 pts/23 00:00:00 sleep
29589 pts/23 00:00:00 ps
Jest to hierarchia procesów, sleep
w której potok jest umieszczony wewnątrz nawiasów klamrowych (czyli w sumie dwa poziomy nawiasów klamrowych)
{ { sleep 2; } | ps -H; }
PID TTY TIME CMD
4398 pts/23 00:00:00 bash
29869 pts/23 00:00:00 bash
29871 pts/23 00:00:00 sleep
29870 pts/23 00:00:00 ps
Dlaczego bash
trzeba utworzyć podpowłokę, aby działała sleep
w trzecim przypadku, gdy dokumentacja stwierdza, że polecenia między nawiasami klamrowymi są wykonywane w bieżącym kontekście powłoki?
{ sleep 2 | command ps -H; }
Odpowiedzi:
W potoku wszystkie polecenia są uruchamiane jednocześnie (z ich stdout / stdin połączonymi rurami), a więc w różnych procesach.
W
Wszystkie trzy polecenia działają w różnych procesach, więc co najmniej dwa z nich muszą działać w procesie potomnym. Niektóre powłoki uruchamiają jedną z nich w bieżącym procesie powłoki (jeśli są wbudowane
read
lub jeśli potok jest ostatnim poleceniem skryptu), alebash
wszystkie działają w osobnym procesie (z wyjątkiemlastpipe
opcji w najnowszychbash
wersjach i pod pewnymi warunkami ).{...}
grupuje polecenia. Jeśli ta grupa jest częścią potoku, musi działać w osobnym procesie, podobnie jak proste polecenie.W:
Potrzebujemy powłoki, aby ocenić, że
a; b "$?"
jest to osobny proces, dlatego potrzebujemy podpowłoki. Powłoka mogłaby zoptymalizować nieb
uruchamiając forka, ponieważ jest to ostatnie polecenie, które można uruchomić w tej grupie. Niektóre pociski to robią, ale najwyraźniej niebash
.źródło
bash -c "sleep 112345 | cat | cat "
, zobaczę, że utworzono tylko jedną bitwę, a następnie 3 dzieci bez żadnych innych przeplatających basów.a; b "$?"
? Czy naprawdę istnieje podstawowa potrzeba na subheel, czy może jest to decyzja / implementacja projektu na bash?eval
), ale ocena (uruchom pierwsze polecenie, poczekaj na niego, uruchom drugie) to zrobione w dziecku, które ma stdout podłączony do rury.{ sleep 2 | ps -H; }
nadrzędnej wersji bash,sleep 2
która wymaga fork / exec. Ale w{ { sleep 2; } | ps -H; }
bashu nadrzędnym widać{ sleep 2; }
innymi słowy, jakiś kod bash. Wygląda na to, że rodzic może obsłużyć fork / exec,sleep 2
ale odradza nowe bash rekurencyjnie, aby obsłużyć napotkany kod bash. Tak rozumiem, czy to ma sens?Zagnieżdżanie nawiasów klamrowych wydaje się oznaczać, że tworzysz dodatkowy poziom zakresu, który wymaga wywołania nowej podpowłoki. Możesz zobaczyć ten efekt z drugą kopią Bash w twoich
ps -H
wynikach.Tylko procesy określone na pierwszym poziomie nawiasów klamrowych są uruchamiane w zakresie oryginalnej powłoki Bash. Wszelkie zagnieżdżone nawiasy klamrowe będą działały we własnej skorupie Bash o określonym zasięgu.
Przykład
Po
| ps -H
usunięciu mieszanki, abyśmy mogli zobaczyć zagnieżdżone nawiasy klamrowe, możemy uruchomićps auxf | less
inną powłokę.Ale czekaj, jest więcej!
Jeśli jednak wyjmiesz rury i użyjesz tej formy polecenia, zobaczymy, czego się właściwie spodziewałbyś:
Teraz w wynikowym oknie zegarka otrzymujemy aktualizację co 2 sekundy tego, co się dzieje:
Oto pierwszy
sleep 10
:Oto drugi
sleep 10
:Oto trzeci
sleep 10
:Zauważ, że wszystkie trzy sny, chociaż wywoływane na różnych poziomach zagnieżdżenia nawiasów klamrowych, faktycznie pozostają w obrębie PID 5676 Bash. Uważam więc, że Twój problem został spowodowany przez samego użytkownika
| ps -H
.Wnioski
Użycie
| ps -H
(tj. Potoku) powoduje dodatkową podpowłokę, więc nie używaj tej metody, gdy próbujesz przesłuchać, co się dzieje.źródło
Zamieszczę wyniki moich testów, co doprowadziło mnie do wniosku, że bash tworzy podpowłokę dla polecenia grupy, i tylko wtedy, gdy jest częścią potoku, to jest tak, jakby ktoś wywołał jakąś funkcję, która byłaby również nazwana w podpowłoce.
źródło