Jak korzystać z polecenia nohup bez uzyskiwania nohup.out?
309
Mam problem z poleceniem nohup.
Kiedy wykonuję pracę, mam dużo danych. Wyjście nohup.out staje się zbyt duże, a mój proces zwalnia. Jak mogę uruchomić to polecenie bez uzyskiwania nohup.out?
nohupKomenda pisze tylko nohup.out, jeśli wyjście w przeciwnym razie przejdź do terminalu. Jeśli przekierowałeś wyjście polecenia gdzie indziej - w tym /dev/null- to właśnie tam idzie.
Jeśli używasz nohup, prawdopodobnie oznacza to, że chcesz uruchomić polecenie w tle, umieszczając kolejne &na końcu całej rzeczy:
nohup command >/dev/null 2>&1 & # runs in background, still doesn't create nohup.out
W systemie Linux uruchomienie zadania z nohupautomatycznie zamyka również dane wejściowe. W innych systemach, w szczególności BSD i macOS, tak nie jest, więc podczas pracy w tle możesz ręcznie zamknąć dane wejściowe. Chociaż zamykanie danych wejściowych nie ma wpływu na tworzenie danych lub ich brak nohup.out, pozwala uniknąć innego problemu: jeśli proces w tle próbuje odczytać cokolwiek ze standardowego wejścia, wstrzymuje się, czekając na przeniesienie go z powrotem na pierwszy plan i wpisanie czegoś. Tak bezpieczna wersja wygląda następująco:
Należy jednak pamiętać, że nie uniemożliwia to bezpośredniemu dostępowi do terminalu ani nie usuwa go z grupy procesów powłoki. Jeśli chcesz zrobić to drugie i uruchamiasz bash, ksh lub zsh, możesz to zrobić, uruchamiając disownbez argumentu jako następną komendę. Oznacza to, że proces w tle nie jest już powiązany z „zadaniem” powłoki i nie będzie przesyłany do niej żadnych sygnałów z powłoki. (Zwróć uwagę na rozróżnienie: disownproces ed nie otrzymuje żadnych sygnałów automatycznie przekazywanych do niego przez powłokę nadrzędną - ale bez nohuptego nadal będzie odbierał HUPsygnał wysyłany innymi środkami, takimi jak killpolecenie ręczne . nohupProces ten ignoruje wszystkie HUPsygnały, bez względu na to, jak zostaną wysłane).
Wyjaśnienie:
W systemach Unixy każde źródło wejściowe lub docelowe dane wyjściowe ma przypisaną liczbę zwaną „deskryptorem pliku” lub w skrócie „fd”. Każdy uruchomiony program („proces”) ma swój własny zestaw, a gdy uruchamia się nowy proces, ma już trzy z nich otwarte: „standardowe wejście”, które ma wartość fd 0, jest otwarte dla procesu do odczytu, podczas gdy „standardowe wyjście” (fd 1) i „standardowy błąd” (fd 2) są otwarte dla niego do zapisu. Jeśli po prostu uruchomisz polecenie w oknie terminala, wówczas domyślnie wszystko, co wpiszesz, trafi do standardowego wejścia, a zarówno standardowe wyjście, jak i błąd standardowy zostaną wysłane do tego okna.
Ale możesz poprosić powłokę o zmianę miejsca, w którym wskazuje jeden lub wszystkie deskryptory plików, przed uruchomieniem polecenia; to co przekierowanie ( <, <<, >, >>) i rura ( |zrobić) operatorzy.
Rura jest najprostsza z tych ... command1 | command2zapewnia standardową moc wyjściową command1bezpośrednio do standardowego wejścia command2. Jest to bardzo przydatne ustawienie, które doprowadziło do określonego wzorca projektowego w narzędziach UNIX (i wyjaśnia istnienie standardowego błędu, który pozwala programowi wysyłać komunikaty do użytkownika, nawet jeśli jego dane wyjściowe trafiają do następnego programu w potoku) . Ale możesz przesyłać tylko standardowe wyjście do standardowego wejścia; nie można wysyłać żadnych innych deskryptorów plików do potoku bez żonglowania.
Operatory przekierowania są bardziej przyjazne, ponieważ pozwalają określić, który deskryptor pliku ma zostać przekierowany. 0<infileCzyta więc standardowe wejście z pliku o nazwie infile, a 2>>logfiledołącza standardowy błąd na końcu pliku o nazwie logfile. Jeśli nie określisz liczby, wówczas przekierowanie wejściowe <przyjmuje domyślnie wartość fd 0 ( jest takie samo jak 0<), podczas gdy przekierowanie wyjściowe >przyjmuje domyślnie wartość fd 1 ( jest takie samo jak 1>).
Możesz także łączyć deskryptory plików razem: 2>&1oznacza „wysyłaj standardowy błąd wszędzie tam, gdzie idzie standardowe wyjście”. Oznacza to, że otrzymujesz pojedynczy strumień wyjściowy, który zawiera zarówno standardowe wyjście, jak i standardowy błąd zmieszany bez możliwości ich oddzielenia, ale oznacza to również, że możesz dołączyć standardowy błąd do potoku.
Tak więc sekwencja >/dev/null 2>&1oznacza „wyślij standardowe wyjście do /dev/null” (które jest specjalnym urządzeniem, które po prostu wyrzuca to, co do niego piszesz) „a następnie wyślij standardowy błąd tam, gdzie idzie standardowe wyjście” (co właśnie upewniliśmy /dev/null). Zasadniczo „wyrzuć cokolwiek to polecenie zapisuje do dowolnego deskryptora pliku”.
Kiedy nohupwykryje, że ani jego standardowy błąd, ani wyjście nie jest podłączone do terminala, nie zawraca sobie głowy tworzeniem nohup.out, ale zakłada, że wyjście jest już przekierowane tam, gdzie użytkownik chce, aby jechał.
/dev/nullUrządzenie pracuje na wejściu, zbyt; jeśli uruchomisz polecenie za pomocą </dev/null, wówczas każda próba odczytania ze standardowego wejścia przez to polecenie natychmiast napotka koniec pliku. Zauważ, że składnia scalania nie będzie miała tego samego efektu; działa tylko w celu wskazania deskryptora pliku na inny, który jest otwarty w tym samym kierunku (wejście lub wyjście). Powłoka na to pozwoli >/dev/null <&1, ale kończy się to tworzeniem procesu z otwartym deskryptorem pliku wejściowego w strumieniu wyjściowym, więc zamiast uderzania w koniec pliku, każda próba odczytu spowoduje krytyczny błąd „nieprawidłowego deskryptora pliku”.
@Tim - że odpowiedź jest poprawna dla Linuksa, ale nie na BSD lub OS X, na którym nohupdziała nie blisko standardowe wejście automatycznie. Zauważ, że nohupnie jest to wbudowana powłoka, ale narzędzie binarne.
Mark Reed
nohup jest częścią coreutils. Czy masz na myśli, że implementacja nohupjest inna dla Linuksa i dla BSD lub OS X?
Tim
Tak. Nazwa „coreutils” odnosi się do pakietu GNU. Ale BSD, OS X, SmartOS / Illumos i wiele komercyjnych Uniksów - w zasadzie tych, które są na rynku dłużej niż GNU - mają podstawowe narzędzia spoza GNU. awkjest inny, sedjest inny, nohupjest inny ...
Czy nie powinno to być >/ dev / null zamiast </ dev / null?
Scott Chu
3
@ ScottChu < /dev/nullprzekierowuje standardowe wejście dla nohup. Linux nie wymaga tego, ale POSIX zezwala na zachowanie, nohupgdy nie można go uruchomić w tle, jeśli jego standardowe wejście jest podłączone do terminala. Przykładami takich systemów są BSD i OS X.
Mikko Rantalainen
8
Możesz użyć programu odłączającego . Używasz go w taki sposób, nohupale nie generuje dziennika wyjściowego, chyba że mu to nakazujesz. Oto strona man:
NAME
detach - run a command after detaching from the terminal
SYNOPSIS
detach [options] [--] command [args]
Forks a new process, detaches is from the terminal, and executes com‐
mand with the specified arguments.
OPTIONS
detach recognizes a couple of options, which are discussed below. The
special option -- is used to signal that the rest of the arguments are
the command and args to be passed to it.
-e file
Connect file to the standard error of the command.
-f Run in the foreground (do not fork).
-i file
Connect file to the standard input of the command.
-o file
Connect file to the standard output of the command.
-p file
Write the pid of the detached process to file.
EXAMPLE
detach xterm
Start an xterm that will not be closed when the current shell exits.
AUTHOR
detach was written by Robbert Haarman. See http://inglorion.net/ for
contact information.
Uwaga: Nie mam powiązań z autorem programu. Jestem tylko zadowolonym użytkownikiem programu.
Odpowiedzi:
nohup
Komenda pisze tylkonohup.out
, jeśli wyjście w przeciwnym razie przejdź do terminalu. Jeśli przekierowałeś wyjście polecenia gdzie indziej - w tym/dev/null
- to właśnie tam idzie.Jeśli używasz
nohup
, prawdopodobnie oznacza to, że chcesz uruchomić polecenie w tle, umieszczając kolejne&
na końcu całej rzeczy:W systemie Linux uruchomienie zadania z
nohup
automatycznie zamyka również dane wejściowe. W innych systemach, w szczególności BSD i macOS, tak nie jest, więc podczas pracy w tle możesz ręcznie zamknąć dane wejściowe. Chociaż zamykanie danych wejściowych nie ma wpływu na tworzenie danych lub ich braknohup.out
, pozwala uniknąć innego problemu: jeśli proces w tle próbuje odczytać cokolwiek ze standardowego wejścia, wstrzymuje się, czekając na przeniesienie go z powrotem na pierwszy plan i wpisanie czegoś. Tak bezpieczna wersja wygląda następująco:Należy jednak pamiętać, że nie uniemożliwia to bezpośredniemu dostępowi do terminalu ani nie usuwa go z grupy procesów powłoki. Jeśli chcesz zrobić to drugie i uruchamiasz bash, ksh lub zsh, możesz to zrobić, uruchamiając
disown
bez argumentu jako następną komendę. Oznacza to, że proces w tle nie jest już powiązany z „zadaniem” powłoki i nie będzie przesyłany do niej żadnych sygnałów z powłoki. (Zwróć uwagę na rozróżnienie:disown
proces ed nie otrzymuje żadnych sygnałów automatycznie przekazywanych do niego przez powłokę nadrzędną - ale beznohup
tego nadal będzie odbierałHUP
sygnał wysyłany innymi środkami, takimi jakkill
polecenie ręczne .nohup
Proces ten ignoruje wszystkieHUP
sygnały, bez względu na to, jak zostaną wysłane).Wyjaśnienie:
W systemach Unixy każde źródło wejściowe lub docelowe dane wyjściowe ma przypisaną liczbę zwaną „deskryptorem pliku” lub w skrócie „fd”. Każdy uruchomiony program („proces”) ma swój własny zestaw, a gdy uruchamia się nowy proces, ma już trzy z nich otwarte: „standardowe wejście”, które ma wartość fd 0, jest otwarte dla procesu do odczytu, podczas gdy „standardowe wyjście” (fd 1) i „standardowy błąd” (fd 2) są otwarte dla niego do zapisu. Jeśli po prostu uruchomisz polecenie w oknie terminala, wówczas domyślnie wszystko, co wpiszesz, trafi do standardowego wejścia, a zarówno standardowe wyjście, jak i błąd standardowy zostaną wysłane do tego okna.
Ale możesz poprosić powłokę o zmianę miejsca, w którym wskazuje jeden lub wszystkie deskryptory plików, przed uruchomieniem polecenia; to co przekierowanie (
<
,<<
,>
,>>
) i rura (|
zrobić) operatorzy.Rura jest najprostsza z tych ...
command1 | command2
zapewnia standardową moc wyjściowącommand1
bezpośrednio do standardowego wejściacommand2
. Jest to bardzo przydatne ustawienie, które doprowadziło do określonego wzorca projektowego w narzędziach UNIX (i wyjaśnia istnienie standardowego błędu, który pozwala programowi wysyłać komunikaty do użytkownika, nawet jeśli jego dane wyjściowe trafiają do następnego programu w potoku) . Ale możesz przesyłać tylko standardowe wyjście do standardowego wejścia; nie można wysyłać żadnych innych deskryptorów plików do potoku bez żonglowania.Operatory przekierowania są bardziej przyjazne, ponieważ pozwalają określić, który deskryptor pliku ma zostać przekierowany.
0<infile
Czyta więc standardowe wejście z pliku o nazwieinfile
, a2>>logfile
dołącza standardowy błąd na końcu pliku o nazwielogfile
. Jeśli nie określisz liczby, wówczas przekierowanie wejściowe<
przyjmuje domyślnie wartość fd 0 ( jest takie samo jak0<
), podczas gdy przekierowanie wyjściowe>
przyjmuje domyślnie wartość fd 1 ( jest takie samo jak1>
).Możesz także łączyć deskryptory plików razem:
2>&1
oznacza „wysyłaj standardowy błąd wszędzie tam, gdzie idzie standardowe wyjście”. Oznacza to, że otrzymujesz pojedynczy strumień wyjściowy, który zawiera zarówno standardowe wyjście, jak i standardowy błąd zmieszany bez możliwości ich oddzielenia, ale oznacza to również, że możesz dołączyć standardowy błąd do potoku.Tak więc sekwencja
>/dev/null 2>&1
oznacza „wyślij standardowe wyjście do/dev/null
” (które jest specjalnym urządzeniem, które po prostu wyrzuca to, co do niego piszesz) „a następnie wyślij standardowy błąd tam, gdzie idzie standardowe wyjście” (co właśnie upewniliśmy/dev/null
). Zasadniczo „wyrzuć cokolwiek to polecenie zapisuje do dowolnego deskryptora pliku”.Kiedy
nohup
wykryje, że ani jego standardowy błąd, ani wyjście nie jest podłączone do terminala, nie zawraca sobie głowy tworzeniemnohup.out
, ale zakłada, że wyjście jest już przekierowane tam, gdzie użytkownik chce, aby jechał./dev/null
Urządzenie pracuje na wejściu, zbyt; jeśli uruchomisz polecenie za pomocą</dev/null
, wówczas każda próba odczytania ze standardowego wejścia przez to polecenie natychmiast napotka koniec pliku. Zauważ, że składnia scalania nie będzie miała tego samego efektu; działa tylko w celu wskazania deskryptora pliku na inny, który jest otwarty w tym samym kierunku (wejście lub wyjście). Powłoka na to pozwoli>/dev/null <&1
, ale kończy się to tworzeniem procesu z otwartym deskryptorem pliku wejściowego w strumieniu wyjściowym, więc zamiast uderzania w koniec pliku, każda próba odczytu spowoduje krytyczny błąd „nieprawidłowego deskryptora pliku”.źródło
nohup
: „jeśli proces później spróbuje odczytać cokolwiek ze standardowego wejścia, zatrzyma się, czekając, aż przeniesiesz go z powrotem na pierwszy plan i coś napiszesz”. wydaje się niepoprawny. Zamiast tegonohup
zamyka standardowe wejście (program nie będzie w stanie odczytać żadnego wejścia, nawet jeśli zostanie uruchomiony na pierwszym planie. Nie zostanie zatrzymany, ale otrzyma kod błędu lub EOF).nohup
działa nie blisko standardowe wejście automatycznie. Zauważ, żenohup
nie jest to wbudowana powłoka, ale narzędzie binarne.nohup
jest inna dla Linuksa i dla BSD lub OS X?awk
jest inny,sed
jest inny,nohup
jest inny ...</dev/null
? Zobacz także0>/dev/null
unix.stackexchange.com/a/266247To wszystko, co musisz zrobić!
źródło
&
ta pozwoli Ci uniknąć konieczności używaniactrl-c
, jeśli jest to dla Ciebie ważne.some_command
danych wyjściowych, w tym błędów.Czy próbowałeś przekierować wszystkie trzy strumienie we / wy:
źródło
>
/ dev / null zamiast </ dev / null?< /dev/null
przekierowuje standardowe wejście dlanohup
. Linux nie wymaga tego, ale POSIX zezwala na zachowanie,nohup
gdy nie można go uruchomić w tle, jeśli jego standardowe wejście jest podłączone do terminala. Przykładami takich systemów są BSD i OS X.Możesz użyć programu odłączającego . Używasz go w taki sposób,
nohup
ale nie generuje dziennika wyjściowego, chyba że mu to nakazujesz. Oto strona man:Uwaga: Nie mam powiązań z autorem programu. Jestem tylko zadowolonym użytkownikiem programu.
źródło
Następujące polecenie pozwoli ci uruchomić coś w tle bez uzyskiwania nohup.out:
W ten sposób będziesz mógł uzyskać dane wyjściowe konsoli podczas uruchamiania skryptu na zdalnym serwerze:
źródło
Przekierowanie wyjścia sudo powoduje, że sudo ponownie podaje hasło, dlatego do wykonania tego wariantu potrzebny jest niezręczny mechanizm.
źródło
Jeśli masz powłokę BASH na swoim komputerze Mac / Linux przed sobą, wypróbuj poniższe kroki, aby zrozumieć przekierowanie praktycznie:
Utwórz 2-wierszowy skrypt o nazwie zz.sh
Obecnie po prostu wykonanie skryptu wysyła zarówno STDOUT, jak i STDERR na ekran.
Teraz zacznij od standardowego przekierowania:
W powyższym wyrażeniu „echo” (STDOUT) przechodzi do pliku zfile.txt. Natomiast „błąd” (STDERR) jest wyświetlany na ekranie.
Powyższe jest takie samo jak:
Teraz możesz spróbować odwrotnie i przekierować „błąd” STDERR do pliku. Polecenie STDOUT z polecenia „echo” przechodzi na ekran.
Łącząc powyższe dwa, otrzymujesz:
Wyjaśnienie:
W końcu możesz spakować całą komendę nohup i uruchomić ją w tle:
źródło
Możesz uruchomić poniższe polecenie.
np. mam polecenie nohup w skrypcie
źródło