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?


Odpowiedzi:


612

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.

 nohup command >/dev/null 2>&1   # doesn't create nohup.out

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:

nohup command </dev/null >/dev/null 2>&1 & # completely detached from terminal 

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”.


1
Jeśli chodzi 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 tego nohup 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).
Tim

1
@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 ...
Mark Reed

Dlaczego napisałeś „wyjątkowo bezpieczny” </dev/null? Zobacz także 0>/dev/null unix.stackexchange.com/a/266247
Tim

68
nohup some_command > /dev/null 2>&1&

To wszystko, co musisz zrobić!


4
Była kolejna odpowiedź, która prawie miała tę samą rzecz, ale nie mieli dodatkowych „&” na końcu.
11101101b

10
Opcja &ta pozwoli Ci uniknąć konieczności używania ctrl-c, jeśli jest to dla Ciebie ważne.
SunSparc

1
Umiejętność biegania w BG jest bardzo pomocna
ist_lion

Jest to przydatne tylko wtedy, gdy nie przejmujesz się przechwytywaniem some_commanddanych wyjściowych, w tym błędów.
wulfgarpro

12

Czy próbowałeś przekierować wszystkie trzy strumienie we / wy:

nohup ./yourprogram > foo.out 2> foo.err < /dev/null &

1
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.


2
Link nie jest zepsuty, a to repozytorium git jest stare. Nie obejmuje aktualnego v0.2.3.
Dan D.

5

Następujące polecenie pozwoli ci uruchomić coś w tle bez uzyskiwania nohup.out:

nohup command |tee &

W ten sposób będziesz mógł uzyskać dane wyjściowe konsoli podczas uruchamiania skryptu na zdalnym serwerze: wprowadź opis zdjęcia tutaj


4
sudo bash -c "nohup /opt/viptel/viptel_bin/log.sh $* &> /dev/null"  &

Przekierowanie wyjścia sudo powoduje, że sudo ponownie podaje hasło, dlatego do wykonania tego wariantu potrzebny jest niezręczny mechanizm.


1

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

#!/bin/bash
echo "Hello. This is a proper command"
junk_errorcommand
  • Dane wyjściowe polecenia echo trafiają do strumienia plików STDOUT (deskryptor pliku 1).
  • Dane wyjściowe polecenia błędu przechodzą do strumienia plików STDERR (deskryptor pliku 2)

Obecnie po prostu wykonanie skryptu wysyła zarówno STDOUT, jak i STDERR na ekran.

./zz.sh

Teraz zacznij od standardowego przekierowania:

zz.sh > zfile.txt

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:

zz.sh 1> zfile.txt

Teraz możesz spróbować odwrotnie i przekierować „błąd” STDERR do pliku. Polecenie STDOUT z polecenia „echo” przechodzi na ekran.

zz.sh 2> zfile.txt

Łącząc powyższe dwa, otrzymujesz:

zz.sh 1> zfile.txt 2>&1

Wyjaśnienie:

  • PIERWSZE, wyślij STDOUT 1 na zfile.txt
  • Następnie wyślij STDERR 2 do samego STDOUT 1 (za pomocą & 1 wskaźnika).
  • Dlatego zarówno 1, jak i 2 przechodzą do tego samego pliku (zfile.txt)

W końcu możesz spakować całą komendę nohup i uruchomić ją w tle:

nohup zz.sh 1> zfile.txt 2>&1&

1

Możesz uruchomić poniższe polecenie.

nohup <your command> & >  <outputfile> 2>&1 &

np. mam polecenie nohup w skrypcie

./Runjob.sh > sparkConcuurent.out 2>&1
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.