Odpowiedzi:
Końcowe &
operatora w celu polecenia w celu wprowadzenia poleceń w tle. Jest to w rzeczywistości standardowa składnia określona przez standard POSIX :
Listy asynchroniczne
Jeśli polecenie zostanie zakończone przez operatora sterującego („&”), powłoka wykona polecenie asynchronicznie w podpowłoce. Oznacza to, że powłoka nie będzie czekać na zakończenie polecenia przed wykonaniem następnego polecenia.
Format uruchamiania polecenia w tle to:
polecenie1 i [polecenie2 i ...]
Celem komend w tle jest uruchomienie komendy bez powłoki głównej w skrypcie lub powłoce interaktywnej czekającej na komendę, co zablokowałoby wykonywanie innych komend i utrudniłoby użytkownikowi czekanie. Jest to przydatne do uruchamiania długo działających poleceń, ale musisz kontynuować pracę w bieżącej powłoce. Jak można się domyślić, wywodzi się z czasów, gdy nie było emulatorów terminali z wieloma kartami, ale terminale były fizycznym sprzętem podłączonym do samego komputera.
Z definicji widać, że &
służy również jako terminator poleceń dla list poleceń, podobnie jak ;
robi. W twoim przykładzie pyprogramm >> /dev/null 2>&1 &
na liście jest tylko jedno polecenie.
Bardziej ogólnie,
echo Hello ; echo World ;
i
echo Hello & echo World &
to dwa przykłady list zakończonych przez operatorów ;
i &
. Jedną różnicą jest to, że do &
zakończonej listy będą podłączone dane wejściowe, /dev/null
jeśli kontrola zadań jest wyłączona:
Jeśli kontrola zadań jest wyłączona (patrz set, -m), standardowe wejście dla listy asynchronicznej, przed wykonaniem jakichkolwiek jawnych przekierowań, będzie uważane za przypisane do pliku, który ma takie same właściwości jak / dev / null. Nie stanie się tak, jeśli włączona jest kontrola zadań. We wszystkich przypadkach wyraźne przekierowanie standardowych danych wejściowych zastępuje tę aktywność.
Jednak na liście sekwencyjnej każde polecenie nadal ma stdin
połączenie z terminalem, jeśli nie ma wyraźnych przekierowań.
Zauważ też, że z definicji, o której wspominaliśmy wcześniej, &
wykonuje polecenia w podpowłoce. Natomiast ;
zakończona lista jest wykonywana w bieżącej powłoce. Istnieją również różnice w statusach wyjściowych. Dla &
średnia mówi:
Status wyjścia listy asynchronicznej wynosi zero.
Jest to istotne, gdy chcesz umieścić wiele poleceń w tle. Kiedy piszesz skrypt lub polecenie, będziesz musiał wybrać polecenia, dla których nie obchodzi cię, czy się nie powiedzie, czy też będziesz musiał znaleźć sposób na obsługę niezerowego (błędu) statusu wyjścia. W konkretnym przykładzie pyprogramm >> /dev/null 2>&1 &
działanie w tle powinno mieć jakiś sposób wskazania, czy nie powiodło się, jednak oceniając, że używasz 2>&1
, ukrywasz wyjście błędu przez przekierowanie i prawdopodobnie zakładasz, że skrypt nie powinien zawieść.
Natomiast ;
status wyjścia jest zdefiniowany jako:
Status wyjścia z listy sekwencyjnej jest statusem wyjścia z ostatniego polecenia na liście.
Ponownie, ma to wpływ na to, jak piszesz sekwencyjną listę poleceń w wierszu poleceń i jak chcesz postępować, jeśli niektóre polecenia na liście zawiodą.
Fakt, że jest to POSIX środki definition że wszystko Bourne'a jak muszle, rozumieniu bash
, dash
i ksh
musi go poprzeć.
&
w przekierowaniu różni się od &
terminatora poleceń. Oznacza duplikowanie (kopiowanie) obiektu deskryptora pliku. Zobacz Co dokładnie oznacza i oznacza przekierowanie danych wyjściowych?
W bash
nie jest |&
operatorem (uwaga nie ma miejsca pomiędzy rurą oraz handlowego). Z podręcznika bash :
Jeśli użyto | &, błąd standardowy polecenia, oprócz standardowego wyjścia, jest podłączony do standardowego wejścia polecenia 2 przez potok; jest skrótem dla 2> i 1 |. To niejawne przekierowanie standardowego błędu na standardowe wyjście jest wykonywane po wszelkich przekierowaniach określonych przez polecenie.
Oznacza to uruchomienie polecenia w tle. Skrypt wywołujący jest kontynuowany, a nie blokuje się, dopóki nie zakończy się wywołane polecenie.
&
ukrywaniu wyjścia, nie brzmi poprawnie. Akapit standardu, który cytujesz, mówi o danych wejściowych , a nie wyjściowych . Powodem rozróżnienia między włączoną kontrolą zadań jest to, że proces w tle próbuje odczytać z tty zostanie zawieszony. W tym momencie musisz użyć kontroli zadań, aby umieścić ją na pierwszym planie, aby zapewnić dane wejściowe, na które czeka. Nie można tego wszystkiego zrobić bez kontroli zadań, a zatem jeśli kontrola zadań jest wyłączona, stdin musi zostać przekierowany z/dev/null
lub równoważny.