Pourquoi `> my.log 2> & 1 &` fait que le travail continue de se déconnecter?

j'utilise

myscript > my.log 2>&1 & 

pour exécuter un script et collecter sa sortie – de sorte que lorsque je me déconnecte – le script sera toujours en cours d'exécution. Je devais le démarrer avec myscript & – il sera terminé juste après la déconnection.

Mais c'est un effet étrange: tout ce que > my.log 2>&1 & fait est de redirect stderr vers stdout …

Pourquoi > my.log 2>&1 & fait que le travail > my.log 2>&1 & à se déconnecter?

Normalement, si vous mettez quelque chose en arrière-plan, il continuera à s'exécuter même après la sortie de son shell parent. En fait, je peux créer un cas de test comme celui-ci:

 /bin/sh -c 'while true; do echo hi; sleep 5; done' & 

et puis quitter le shell et en utilisant ps je peux voir qu'il est toujours en cours d'exécution, pour toujours, jusqu'à ce que je le tue.

Il y a une différence entre redirect la sortie et non: si vous ne redirigez pas la sortie et que vous quittez votre shell, les descripteurs de files stdout / stderr sont fermés et la prochaine fois que vous essaierez de leur écrire, l'opération d'écriture échouera. Si votre script vérifie cela ou si vous utilisez l'option -e (exit on error), votre script s'arrêtera. Comparez le comportement de ce qui précède avec cette version:

 /bin/sh -c 'while true; do echo hi || exit 1; sleep 5; done' & 

ou

 /bin/sh -ec 'while true; do echo hi; sleep 5; done' & 

Si vous laissez cette exécution, quittez le shell et utilisez ps vous verrez que quand il essaye d'exécuter l' echo il échouera et quittera.

Si vous redirigiez la sortie vers un file, l'écriture n'échouera plus et le script continuera à s'exécuter.

Le > my.log 2>&1 n'a rien à voir avec ça. La finale & place, a le rôle d'exécuter un process en arrière-plan. La ligne renvoyée après l'input de la command doit afficher un numéro qui est l' process id du process id (pid.). Vous pouvez ensuite utiliser ce numéro avec la command kill pour terminer le process si nécessaire.

Même si, pour votre cas, je voudrais tout exécuter dans un screen . Vous pouvez démarrer un écran en utilisant

 screen -S <name> 

et ensuite exécuter votre command. Pour se détacher d'un écran (return à votre terminal initial), vous devez appuyer sur CTRL et dans l'ordre appuyer sur A et D Pour rattacher un écran, tapez:

 screen -r <name> 

Comme cela (exécuter la tâche dans un écran), il s'exécute même si l'user se déconnecte / se déconnecte et la meilleure partie est que vous obtenez de voir les résultats avec la command reattach.

Comparons un process immortel à un démon. Un démon n'interagit avec aucun user ou terminal, et il meurt quand init meurt (à less qu'il ne soit arrêté volontairement).

vous pouvez "créer un démon" avec nohup et en redirigeant vers / dev / null le std.out & std.err

nohup ping google.com 2> / dev / null> / dev / null – CECI EST IMMORTEL.