Skip to content

Jak uruchomić polecenie w tle bez wyjścia, chyba że wystąpi błąd?

2 de sierpień de 2021
run a command in the background with no output unless there is an error 00

Jeśli jesteś osobą zajętą, to ostatnią rzeczą, której potrzebujesz, jest zawracanie sobie głowy ogromną liczbą „bezużytecznych” powiadomień, więc jak możesz to wyciszyć? Dzisiejszy post z pytaniami i odpowiedziami dla SuperUser zawiera świetne odpowiedzi, które pomogą czytelnikowi wyciszyć ilość danych wyjściowych.

Dzisiejsza sesja pytań i odpowiedzi przychodzi do nas dzięki uprzejmości SuperUser — pododdziału Stack Exchange, społecznościowej grupy witryn internetowych z pytaniami i odpowiedziami.

Pytanie

Czytnik SuperUser Xster chce wiedzieć, jak uruchomić polecenie w tle bez wyjścia, chyba że wystąpi błąd:

Jak pominąć dane wyjściowe polecenia, ale pokazać je, jeśli wyjście polecenia koduje błąd?

Jak uzyskać polecenie do uruchomienia w tle bez danych wyjściowych, chyba że wystąpi błąd?

Odpowiedź

Współtwórcy SuperUser Bob i Maximillian Laumeister mają dla nas odpowiedź. Po pierwsze, Bob:

Niestety założenie, że stderr jest używany tylko do wyprowadzania błędów nie zawsze jest poprawny. Raczej, stderr jest często używany do wszelkich interaktywnych danych wyjściowych i diagnostycznych (tj. danych wyjściowych przeznaczonych do odczytania przez użytkownika w interaktywnym podpowiedzi).(1) wget oraz dd są dobrze znanymi przykładami.

Niektóre polecenia podadzą flagę (np -cichy lub -cichy), aby pominąć dane wyjściowe bez błędów. Przeczytaj ich strony podręcznika, aby zobaczyć, czy taki istnieje.

Inną konwencją, która występuje częściej, jest kod wyjścia, program zwraca kod zakończenia po zakończeniu. Zazwyczaj(2), kod wyjścia z 0 wskazuje powodzenie, a każdy inny kod zakończenia wskazuje błąd.

Z grzmotnąć, możesz uzyskać kod wyjścia ostatniego polecenia z $? zmienny. w ryba, Użyj $status zmienny. Możesz fajkować stderr do pliku tymczasowego i drukuj go tylko wtedy, gdy wystąpi błąd. Na przykład (ryba):

1627894800 749 Jak uruchomic polecenie w tle bez wyjscia chyba ze wystapi

Możesz także użyć niektórych skrótów, jeśli nie łączysz poleceń:

1627894800 434 Jak uruchomic polecenie w tle bez wyjscia chyba ze wystapi

Lub:

1627894800 707 Jak uruchomic polecenie w tle bez wyjscia chyba ze wystapi

Możesz także fajkować stdout do tego samego bufora za pomocą 2>&1>/tmp/bufor wyjściowy.

(Notatka: właściwie nie wiem ryba, więc dostosowuję koncepcję do tego, co mogę znaleźć w jego dokumentacji. Składnia może być nieco nieprawidłowa. Możesz również użyć mktemp aby wygenerować unikalny plik tymczasowy. Uruchom go i zapisz nazwę pliku w zmiennej).

Jeśli musisz uruchomić całość w tle powłoki, z której jednocześnie korzystasz interaktywnie, lepiej napisać skrypt obsługujący ukrywanie danych wyjściowych i uruchamianie tego skryptu w tle za pomocą funkcji standardowe techniki (ryba). Heck, możesz umieścić coś takiego jak następująca funkcja w ~/.config/fish/config.fish:

1627894800 960 Jak uruchomic polecenie w tle bez wyjscia chyba ze wystapi

Zadzwoń z cisza, jakieś polecenie i (gdzie kończą się & powoduje, że działa w tle)

Zauważ, że to połknie oryginalny kod wyjścia i zrzuci oba stdout oraz stderr w przypadku awarii. Możesz go dostosować w razie potrzeby.

(1) Nie ma gwarancji, że wyjście błędu nie pojawi się na stdout, niektóre programy zrzucą tam wszystkie dane wyjściowe!

(2) Niestety nadal nie zawsze tak jest. Kod zakończenia jest całkowicie kontrolowany przez program, a niektóre wskazują pewne warunki powodzenia z niezerowymi wyjściami. Ponownie sprawdź instrukcję.

Następnie odpowiedź od Maximilliana Laumeistera:

Narzędzia uniksowe wysyłają ogólne wiadomości do stdouti komunikaty o błędach do stderr, więc jeśli chcemy tylko widzieć komunikaty o błędach, to wystarczy pominąć stdout więc tylko stderr pobiera dane wyjściowe do konsoli.

Sposób na zrobienie tego (w obu grzmotnąć oraz ryba) ma dołączyć >/dev/null do polecenia. Te rury stdout w nicość, ale stderr (z twoimi komunikatami o błędach) nadal dociera do konsoli.

Na przykład:

Komenda echo 1 >/dev/null nie drukuje nic, bo normalna stdout wyjście jest tłumione i nic nie zostało zapisane stderr.

Komenda człowiek nie istnieje >/dev/null wyświetla komunikat o błędzie, ponieważ facet zapisuje swój komunikat o błędzie do stderr.

Masz coś do dodania do wyjaśnienia? Dźwięk w komentarzach. Chcesz przeczytać więcej odpowiedzi od innych doświadczonych technologicznie użytkowników Stack Exchange? Sprawdź pełny wątek dyskusji tutaj.

Czy ten post był pomocny?