Come posso usare il comando nohup senza ottenere nohup.out?


309

Ho un problema con il comando nohup.

Quando eseguo il mio lavoro, ho molti dati. L'output nohup.out diventa troppo grande e il mio processo rallenta. Come posso eseguire questo comando senza ottenere nohup.out?


Risposte:


612

Il nohupcomando scrive solo nohup.outse l'output andrebbe altrimenti al terminale. Se hai reindirizzato l'output del comando da qualche altra parte - incluso /dev/null- è lì che va invece.

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

Se lo stai usando nohup, probabilmente significa che vuoi eseguire il comando in background inserendone un altro &alla fine di tutto:

 nohup command >/dev/null 2>&1 & # runs in background, still doesn't create nohup.out

Su Linux, l'esecuzione di un lavoro con nohupchiude automaticamente anche il suo input. Su altri sistemi, in particolare BSD e macOS, non è così, quindi quando si esegue in background, è possibile chiudere manualmente l'input. Mentre la chiusura dell'input non ha alcun effetto sulla creazione o meno di nohup.out, evita un altro problema: se un processo in background tenta di leggere qualcosa dall'input standard, si fermerà, aspettando che tu lo riporti in primo piano e digiti qualcosa. Quindi la versione extra-sicura si presenta così:

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

Si noti, tuttavia, che ciò non impedisce al comando di accedere direttamente al terminale, né lo rimuove dal gruppo di processi della shell. Se si desidera eseguire quest'ultima operazione e si esegue bash, ksh o zsh, è possibile farlo eseguendo disownsenza argomento come comando successivo. Ciò significa che il processo in background non è più associato a un "lavoro" della shell e non avrà alcun segnale inoltrato dalla shell. (Nota la distinzione: un disownprocesso ed non riceve alcun segnale inoltrato automaticamente dal suo guscio principale - ma senza nohup, riceverà comunque un HUPsegnale inviato con altri mezzi, come un killcomando manuale . Un nohupprocesso "ed" ignora tutti i HUPsegnali, non importa come vengono inviati.)

Spiegazione:

Nei sistemi Unixy, ogni sorgente di input o target di output ha un numero associato ad esso chiamato "descrittore di file", o "fd" in breve. Ogni programma in esecuzione ("processo") ne ha una propria serie e quando un nuovo processo si avvia ne ha già tre aperti: "input standard", che è fd 0, è aperto per la lettura del processo, mentre "output standard" (fd 1) e "errore standard" (fd 2) sono aperti per la scrittura. Se si esegue semplicemente un comando in una finestra del terminale, per impostazione predefinita, tutto ciò che si digita va al suo input standard, mentre sia il suo output standard che l'errore standard vengono inviati a quella finestra.

Ma puoi chiedere alla shell di cambiare dove uno o tutti quei descrittori di file puntano prima di lanciare il comando; questo è ciò che il reindirizzamento ( <, <<, >, >>) e tubo ( |operatori) fanno.

Il tubo è il più semplice di questi ... command1 | command2organizza l'output standard di command1per alimentare direttamente l'input standard di command2. Questa è una disposizione molto utile che ha portato a un particolare modello di progettazione negli strumenti UNIX (e spiega l'esistenza di un errore standard, che consente a un programma di inviare messaggi all'utente anche se il suo output sta andando al programma successivo nella pipeline) . Ma puoi solo reindirizzare l'output standard all'input standard; non è possibile inviare altri descrittori di file a una pipe senza giocoleria.

Gli operatori di reindirizzamento sono più amichevoli in quanto consentono di specificare quale descrittore di file reindirizzare. Quindi 0<infilelegge l'input standard dal file denominato infile, mentre 2>>logfileaggiunge l'errore standard alla fine del file denominato logfile. Se non si specifica un numero, immettere i valori predefiniti di reindirizzamento su fd 0 ( <è uguale a 0<), mentre il reindirizzamento di default su fd 1 ( >è uguale a 1>).

Inoltre, puoi combinare insieme i descrittori di file: 2>&1significa "invia errore standard ovunque stia andando l'output standard". Ciò significa che si ottiene un singolo flusso di output che include sia l'uscita standard che l'errore standard mescolati senza alcun modo per separarli più, ma significa anche che è possibile includere l'errore standard in una pipe.

Quindi la sequenza >/dev/null 2>&1significa "invia l'output standard a /dev/null" (che è un dispositivo speciale che getta via qualunque cosa tu scriva ad esso) "e quindi invia l'errore standard ovunque vada l'output standard" (cosa che ci siamo appena assicurati che fosse /dev/null). Fondamentalmente, "butta via qualsiasi cosa questo comando scriva su entrambi i descrittori di file".

Quando nohuprileva che né il suo errore standard né l'output sono collegati a un terminale, non si preoccupa di creare nohup.out, ma presuppone che l'output sia già reindirizzato dove l'utente vuole che vada.

Il /dev/nulldispositivo funziona anche per l'input; se si esegue un comando con </dev/null, qualsiasi tentativo da parte di quel comando di leggere dall'input standard incontrerà immediatamente la fine del file. Si noti che la sintassi di unione non avrà lo stesso effetto qui; funziona solo per indicare un descrittore di file a un altro aperto nella stessa direzione (input o output). La shell ti permetterà di farlo >/dev/null <&1, ma questo finisce per creare un processo con un descrittore di file di input aperto su un flusso di output, quindi invece di colpire solo la fine del file, qualsiasi tentativo di lettura attiverà un errore fatale "descrittore di file non valido".


1
Per quanto riguarda nohup"se il processo in seguito tenta di leggere qualcosa dall'input standard, si fermerà, aspettando che tu lo riporti in primo piano e digiti qualcosa". sembra errato. Invece, nohup chiude standard input (il programma non sarà in grado di leggere qualsiasi ingresso, anche se viene eseguito in primo piano. Non viene arrestata, ma riceverà un codice di errore o EOF).
Tim

1
@ Tim - la risposta è corretta per Linux, ma non per BSD o OS X, su cui nohupnon non ingresso vicino di serie automaticamente. Nota che nohupnon è un built-in di shell ma un'utilità binaria.
Mark Reed

nohup fa parte dei coreutils. Vuoi dire che l'implementazione di nohupè diversa per Linux e per BSD o OS X?
Tim

Sì. Il nome "coreutils" si riferisce a un pacchetto GNU. Ma BSD, OS X, SmartOS / Illumos e molti Unix commerciali - fondamentalmente, quelli che sono stati in giro più a lungo di GNU - hanno utility core non GNU. awkè diverso, sedè diverso, nohupè diverso ...
Mark Reed

Perché hai scritto "extra safe" di </dev/null? Vedi anche 0>/dev/null unix.stackexchange.com/a/266247
Tim

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

Questo è tutto ciò che devi fare!


4
C'era un'altra risposta che aveva quasi la stessa cosa, ma alla fine non avevano il "&" in più.
11101101b,

10
L' &accensione ti impedirà di utilizzare ctrl-c, se questo è importante per te.
SunSparc,

1
La possibilità di correre in BG è molto utile
ist_lion

Questo è utile solo se non ti preoccupi della cattura some_commanddell'output, incluso l'errore.
wulfgarpro,

12

Hai provato a reindirizzare tutti e tre i flussi I / O:

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

1
Non dovrebbe essere >/ dev / null piuttosto che </ dev / null?
Scott Chu,

3
@ScottChu < /dev/nullreindirizza l'input standard per nohup. Linux non lo richiede, ma POSIX consente comportamenti che nohupnon possono essere eseguiti in background se il suo input standard è collegato al terminale. Esempi di tali sistemi sono BSD e OS X.
Mikko Rantalainen,

8

Potresti voler usare il programma di distacco . Lo usi come, nohupma non produce un registro di output se non glielo dici. Ecco la pagina 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.

Nota Non ho alcuna affiliazione con l'autore del programma. Sono solo un utente soddisfatto del programma.


2
Il collegamento non è interrotto e quel repository git è vecchio. Non include l'attuale v0.2.3.
Dan D.

5

Il seguente comando ti consentirà di eseguire qualcosa in background senza ottenere nohup.out:

nohup command |tee &

In questo modo, sarai in grado di ottenere l'output della console durante l'esecuzione di script sul server remoto: inserisci qui la descrizione dell'immagine


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

Il reindirizzamento dell'output di sudo fa sì che sudo riesca a cercare la password, quindi è necessario un meccanismo imbarazzante per fare questa variante.


1

Se hai una shell BASH sul tuo mac / linux di fronte a te, prova i passaggi seguenti per capire praticamente il reindirizzamento:

Crea uno script di 2 righe chiamato zz.sh

#!/bin/bash
echo "Hello. This is a proper command"
junk_errorcommand
  • L'output del comando echo va nel filestream STDOUT (descrittore di file 1).
  • L'output del comando di errore va nel filestream STDERR (descrittore di file 2)

Attualmente, semplicemente eseguendo lo script viene inviato sullo schermo sia STDOUT che STDERR.

./zz.sh

Ora inizia con il reindirizzamento standard:

zz.sh > zfile.txt

In quanto sopra, "echo" (STDOUT) va in zfile.txt. Mentre "errore" (STDERR) viene visualizzato sullo schermo.

Quanto sopra è uguale a:

zz.sh 1> zfile.txt

Ora puoi provare il contrario e reindirizzare "errore" STDERR nel file. Il comando STDOUT da "echo" va sullo schermo.

zz.sh 2> zfile.txt

Combinando i due precedenti, ottieni:

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

Spiegazione:

  • PRIMO, invia STDOUT 1 a zfile.txt
  • POI, inviare STDERR 2 a STDOUT 1 stesso (usando il puntatore & 1).
  • Pertanto, sia 1 che 2 vanno nello stesso file (zfile.txt)

Alla fine, puoi impacchettare tutto all'interno del comando nohup e eseguirlo in background:

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

1

È possibile eseguire il comando seguente.

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

ad es. ho un comando nohup all'interno dello script

./Runjob.sh > sparkConcuurent.out 2>&1
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.