Comment utiliser la commande nohup sans obtenir nohup.out?

309

J'ai un problème avec la commande nohup.

Lorsque j'exécute mon travail, j'ai beaucoup de données. La sortie nohup.out devient trop volumineuse et mon processus ralentit. Comment puis-je exécuter cette commande sans obtenir nohup.out?

Ofer
la source

Réponses:

612

La nohupcommande n'écrit que nohup.outsi la sortie irait autrement au terminal. Si vous avez redirigé la sortie de la commande ailleurs - y compris /dev/null- c'est là que ça va à la place.

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

Si vous utilisez nohup, cela signifie probablement que vous souhaitez exécuter la commande en arrière-plan en en mettant une autre &à la fin de l'ensemble:

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

Sous Linux, l'exécution d'un travail avec nohupferme automatiquement son entrée également. Sur d'autres systèmes, notamment BSD et macOS, ce n'est pas le cas, donc lors de l'exécution en arrière-plan, vous voudrez peut-être fermer manuellement l'entrée. Bien que la fermeture de l'entrée n'ait aucun effet sur la création ou non de nohup.out, cela évite un autre problème: si un processus d'arrière-plan essaie de lire quoi que ce soit à partir de l'entrée standard, il s'arrêtera, vous attendant de le ramener au premier plan et de taper quelque chose. Ainsi, la version extra-sûre ressemble à ceci:

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

Notez cependant que cela n'empêche pas la commande d'accéder directement au terminal, ni de le supprimer du groupe de processus de votre shell. Si vous souhaitez effectuer cette dernière opération et que vous exécutez bash, ksh ou zsh, vous pouvez le faire en exécutant disownsans argument comme commande suivante. Cela signifie que le processus d'arrière-plan n'est plus associé à un «travail» de shell et qu'aucun signal ne lui sera transmis depuis le shell. (Notez la distinction: un disownprocessus ed ne reçoit aucun signal qui lui est transmis automatiquement par son shell parent - mais sans nohup, il recevra toujours un HUPsignal envoyé par d'autres moyens, comme une killcommande manuelle . Un nohupprocessus ed ignore tous les HUPsignaux, peu importe comment ils sont envoyés.)

Explication:

Dans les systèmes Unixy, chaque source d'entrée ou cible de sortie est associée à un numéro appelé "descripteur de fichier", ou "fd" pour faire court. Chaque programme en cours d'exécution ("processus") a son propre ensemble de ceux-ci, et lorsqu'un nouveau processus démarre, trois d'entre eux sont déjà ouverts: "l'entrée standard", qui est fd 0, est ouverte pour la lecture du processus, tandis que "sortie standard" (fd 1) et "erreur standard" (fd 2) sont ouverts pour l'écriture. Si vous exécutez simplement une commande dans une fenêtre de terminal, par défaut, tout ce que vous tapez va à son entrée standard, tandis que sa sortie standard et son erreur standard sont envoyées à cette fenêtre.

Mais vous pouvez demander au shell de changer où certains ou tous ces descripteurs de fichiers pointent avant de lancer la commande; c'est ce que la redirection ( <, <<, >, >>) et la conduite ( |opérateurs) font.

Le tuyau est le plus simple de ceux-ci ... command1 | command2dispose que la sortie standard de command1alimente directement l'entrée standard de command2. Il s'agit d'un arrangement très pratique qui a conduit à un modèle de conception particulier dans les outils UNIX (et explique l'existence d'une erreur standard, qui permet à un programme d'envoyer des messages à l'utilisateur même si sa sortie va dans le programme suivant dans le pipeline) . Mais vous ne pouvez diriger que la sortie standard vers l'entrée standard; vous ne pouvez pas envoyer d'autres descripteurs de fichiers à un tuyau sans jongler.

Les opérateurs de redirection sont plus conviviaux dans la mesure où ils vous permettent de spécifier le descripteur de fichier à rediriger. 0<infileLit donc l'entrée standard du fichier nommé infile, tout en 2>>logfileajoutant l'erreur standard à la fin du fichier nommé logfile. Si vous ne spécifiez pas de nombre, la redirection d'entrée par défaut est fd 0 ( <identique à 0<), tandis que la redirection de sortie par défaut est fd 1 ( >identique à 1>).

En outre, vous pouvez combiner les descripteurs de fichiers ensemble: 2>&1signifie "envoyer une erreur standard partout où la sortie standard va". Cela signifie que vous obtenez un seul flux de sortie qui inclut à la fois la sortie standard et l'erreur standard mélangée sans aucun moyen de les séparer, mais cela signifie également que vous pouvez inclure l'erreur standard dans un tube.

Ainsi, la séquence >/dev/null 2>&1signifie "envoyer une sortie standard vers /dev/null" (qui est un périphérique spécial qui jette tout ce que vous y écrivez) "", puis envoyer une erreur standard là où la sortie standard va "(ce que nous venons de vérifier /dev/null). Fondamentalement, "jetez tout ce que cette commande écrit dans l'un ou l'autre descripteur de fichier".

Lorsque nohupdétecte que ni son erreur standard ni sa sortie ne sont attachées à un terminal, il ne prend pas la peine de créer nohup.out, mais suppose que la sortie est déjà redirigée là où l'utilisateur veut qu'elle aille.

L' /dev/nullappareil fonctionne également pour l'entrée; si vous exécutez une commande avec </dev/null, alors toute tentative par cette commande de lire à partir de l'entrée standard rencontrera instantanément la fin du fichier. Notez que la syntaxe de fusion n'aura pas le même effet ici; cela ne fonctionne que pour pointer un descripteur de fichier vers un autre qui est ouvert dans la même direction (entrée ou sortie). Le shell vous laisse faire >/dev/null <&1, mais cela finit par créer un processus avec un descripteur de fichier d'entrée ouvert sur un flux de sortie, donc au lieu de simplement appuyer sur la fin du fichier, toute tentative de lecture déclenchera une erreur fatale de "descripteur de fichier invalide".

Mark Reed
la source
1
Concernant nohup, "si le processus essaye plus tard de lire quoi que ce soit à partir de l'entrée standard, il s'arrêtera, en attendant que vous le remettiez au premier plan et que vous tapiez quelque chose." semble incorrect. Au lieu de cela, nohup ferme l'entrée standard (le programme ne pourra lire aucune entrée, même s'il est exécuté au premier plan. Il n'est pas arrêté, mais recevra un code d'erreur ou EOF).
Tim
1
@Tim - cette réponse est correcte pour Linux, mais pas pour BSD ou OS X, sur lequel nohupne ferme pas automatiquement l'entrée standard. Notez que ce nohupn'est pas un shell intégré mais un utilitaire binaire.
Mark Reed
nohup fait partie de coreutils. Voulez-vous dire la mise en œuvre denohup est différente pour Linux et pour BSD ou OS X?
Tim
Oui. Le nom "coreutils" fait référence à un paquet GNU. Mais BSD, OS X, SmartOS / Illumos et de nombreux Unix commerciaux - essentiellement ceux qui existent depuis plus longtemps que GNU - ont des utilitaires de base non GNU. awkest différent, sedest différent,nohup est différent ...
Mark Reed
Pourquoi avez-vous écrit "extra safe" par </dev/null? Voir également 0>/dev/null unix.stackexchange.com/a/266247
Tim
68
nohup some_command > /dev/null 2>&1&

C'est tout ce que vous devez faire!

11101101b
la source
4
Il y avait une autre réponse qui avait presque la même chose, mais ils n'avaient pas le "&" supplémentaire à la fin.
11101101b
10
Le &sur le vous empêchera d'avoir besoin d'utiliser ctrl-c, si cela vous intéresse.
SunSparc
1
La possibilité d'exécuter en BG est très utile
ist_lion
Cela n'est utile que si vous n'êtes pas inquiet de capturer la some_commandsortie, y compris l'erreur.
wulfgarpro
12

Avez-vous essayé de rediriger les trois flux d'E / S:

nohup ./yourprogram > foo.out 2> foo.err < /dev/null &
Aziz Shaikh
la source
1
Cela ne devrait-il pas être >/ dev / null plutôt que </ dev / null?
Scott Chu
3
@ScottChu < /dev/nullredirige l'entrée standard pour nohup. Linux ne l'exige pas mais POSIX permet un comportement qui nohupne peut pas s'exécuter en arrière-plan si son entrée standard est connectée au terminal. Des exemples de tels systèmes sont BSD et OS X.
Mikko Rantalainen
8

Vous voudrez peut-être utiliser le programme de détachement . Vous l'utilisez comme nohupmais il ne produit pas de journal de sortie sauf si vous le lui demandez. Voici la page de manuel:

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.

Remarque Je n'ai aucune affiliation avec l'auteur du programme. Je ne suis qu'un utilisateur satisfait du programme.

Dan D.
la source
2
Le lien n'est pas rompu et ce git repo est ancien. Il n'inclut pas la v0.2.3 actuelle.
Dan D.20
5

La commande suivante vous permettra d'exécuter quelque chose en arrière-plan sans obtenir nohup.out:

nohup command |tee &

De cette façon, vous pourrez obtenir la sortie de la console tout en exécutant le script sur le serveur distant: entrez la description de l'image ici

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

La redirection de la sortie de sudo fait que sudo recherche le mot de passe, donc un mécanisme maladroit est nécessaire pour faire cette variante.

Kjeld Flarup
la source
1

Si vous avez un shell BASH sur votre mac / linux devant vous, vous essayez les étapes ci-dessous pour comprendre la redirection pratiquement:

Créez un script de 2 lignes appelé zz.sh

#!/bin/bash
echo "Hello. This is a proper command"
junk_errorcommand
  • La sortie de la commande echo va dans STDOUT filestream (descripteur de fichier 1).
  • La sortie de la commande d'erreur va dans le flux de fichiers STDERR (descripteur de fichier 2)

Actuellement, l'exécution du script envoie simplement STDOUT et STDERR à l'écran.

./zz.sh

Commençons maintenant par la redirection standard:

zz.sh > zfile.txt

Dans ce qui précède, "echo" (STDOUT) va dans le fichier zfile.txt. Tandis que "erreur" (STDERR) s'affiche à l'écran.

Ce qui précède est le même que:

zz.sh 1> zfile.txt

Vous pouvez maintenant essayer le contraire et rediriger STDERR "error" dans le fichier. La commande STDOUT de "echo" va à l'écran.

zz.sh 2> zfile.txt

En combinant les deux ci-dessus, vous obtenez:

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

Explication:

  • D'abord, envoyez STDOUT 1 à zfile.txt
  • ALORS, envoyez STDERR 2 à STDOUT 1 lui-même (en utilisant le pointeur & 1).
  • Par conséquent, 1 et 2 vont dans le même fichier (zfile.txt)

Finalement, vous pouvez emballer le tout dans la commande nohup & pour l'exécuter en arrière-plan:

nohup zz.sh 1> zfile.txt 2>&1&
Thyag
la source
1

Vous pouvez exécuter la commande ci-dessous.

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

par exemple, j'ai une commande nohup dans le script

./Runjob.sh > sparkConcuurent.out 2>&1
Prem S
la source