Jakie jest znaczenie & na końcu polecenia?

12

Mam wiersz skryptu uruchamiania:

pyprogramm >> /dev/null  2>&1 &

Znaczenie:

>> /dev/null - redirect stdout to null device
2>&1 - redirect stderr to stdout (that is redirected to null device)

ale co oznacza ostatni &?

Vico
źródło

Odpowiedzi:

16

Co to jest & terminator?

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.

Sekwencyjny ; listy vs asynchroniczne i listy

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/nulljeś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 stdinpołą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ą.


Notatki dodatkowe i dodatkowe lektury

  • Fakt, że jest to POSIX środki definition że wszystko Bourne'a jak muszle, rozumieniu bash, dashi kshmusi 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 bashnie 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.

Sergiy Kolodyazhnyy
źródło
2
To, co mówisz o &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/nulllub równoważny.
kasperd
Zauważyłem także błąd w twojej edycji. W jednym miejscu napisałeś włączone, gdzie powinieneś napisać wyłączone.
kasperd
@kasperd Tak, właśnie ponownie przeczytałem stronę POSIX, kiedy to zauważyłem. Juz naprawione. Daj mi znać, jeśli coś jeszcze wymaga edycji. Dzięki :)
Sergiy Kolodyazhnyy
3

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.

Robert Longson
źródło
0

&to zwraca kontrolę skryptu do systemu operacyjnego, ale wysłało odpowiedź w tle, ponieważ nohupbezpośrednio wysyła całe wykonanie

Bryro
źródło