310 votes

Comment empêcher l'arrêt d'un processus en arrière-plan après la fermeture du client SSH sous Linux ?

Je travaille sur une machine Linux via SSH (Putty). J'ai besoin de laisser un processus en cours d'exécution pendant la nuit, et j'ai pensé que je pourrais le faire en démarrant le processus en arrière-plan (avec une esperluette à la fin de la commande) et en redirigeant stdout vers un fichier.

À ma grande surprise, cela ne fonctionne pas. Dès que je ferme la fenêtre Putty, le processus est arrêté.

Comment puis-je empêcher que cela se produise ?

0 votes

Si vous voulez forcer la session à rester ouverte, voir stackoverflow.com/questions/25084288/keep-ssh-session-alive

315voto

JesperE Points 34356

Consultez le " nohup programme ".

4 votes

Comment l'arrêter ensuite ?

9 votes

Connectez-vous et faites "kill <pid>". Utilisez "pidof" si vous ne connaissez pas le pid.

38 votes

Vous pouvez utiliser nohup command > /dev/null 2>&1 & pour fonctionner en arrière-plan sans créer de sortie stdout ou stderr (no nohup.out fichier)

171voto

gpojd Points 12043

Je recommande d'utiliser Écran GNU . Il vous permet de vous déconnecter du serveur alors que tous vos processus continuent de s'exécuter. Je ne sais pas comment j'ai pu vivre sans lui avant de connaître son existence.

7 votes

C'est l'un des meilleurs logiciels que j'ai jamais utilisé. Sérieusement. Je l'ai fait tourner sur une boîte BSD à laquelle j'accède par ssh de PARTOUT, et je peux simplement me rattacher à mon écran et avoir tous mes terminaux où je fais toutes sortes de choses.

1 votes

Je peux en témoigner. L'écran est une excellente application. La possibilité de ré-attacher est étonnante, et permet d'éviter beaucoup de travail potentiellement perdu.

0 votes

Je l'utilise même sur des machines locales, et j'attache plusieurs xterms à la même session d'écran (screen -x). De cette façon, je peux ouvrir plusieurs fenêtres dans ma session d'écran, et passer librement de mes différents xterms d'une fenêtre à l'autre.

82voto

Robert Gamble Points 41984

Lorsque la session est fermée, le processus reçoit le signal SIGHUP qu'il ne semble pas avoir capté. Vous pouvez utiliser la fonction nohup lors du lancement du processus ou la commande intégrée bash disown -h après avoir lancé le processus pour éviter que cela ne se produise :

> help disown
disown: disown [-h] [-ar] [jobspec ...]
     By default, removes each JOBSPEC argument from the table of active jobs.
    If the -h option is given, the job is not removed from the table, but is
    marked so that SIGHUP is not sent to the job if the shell receives a
    SIGHUP.  The -a option, when JOBSPEC is not supplied, means to remove all
    jobs from the job table; the -r option means to remove only running jobs.

4 votes

L'avantage ici est que le désaveu fonctionne pour les processus qui ont déjà été lancés.

1 votes

Est-ce que 'jobpec' signifie le pid ?

1 votes

Pas de soucis, j'ai trouvé cette réponse ici stackoverflow.com/questions/625409/

45voto

anthonyrisinger Points 1245

Daemonize ? nohup ? SCREEN ? (tmux ftw, screen est de la camelote ;-)

Faites juste ce que toutes les autres applications ont fait depuis le début : une double fourchette.

# ((exec sleep 30)&)
# grep PPid /proc/`pgrep sleep`/status
PPid:   1
# jobs
# disown
bash: disown: current: no such job

Bang ! C'est fait :-) J'ai utilisé cette méthode d'innombrables fois sur tous les types d'applications et sur de nombreuses vieilles machines. Vous pouvez combiner avec des redirections et autres pour ouvrir un canal privé entre vous et le processus.

Créer comme coproc.sh :

#!/bin/bash

IFS=

run_in_coproc () {
    echo "coproc[$1] -> main"
    read -r; echo $REPLY
}

# dynamic-coprocess-generator. nice.
_coproc () {
    local i o e n=${1//[^A-Za-z0-9_]}; shift
    exec {i}<> <(:) {o}<> >(:) {e}<> >(:)
. /dev/stdin <<COPROC "${@}"
    (("\$@")&) <&$i >&$o 2>&$e
    $n=( $o $i $e )
COPROC
}

# pi-rads-of-awesome?
for x in {0..5}; do
    _coproc COPROC$x run_in_coproc $x
    declare -p COPROC$x
done

for x in COPROC{0..5}; do
. /dev/stdin <<RUN
    read -r -u \${$x[0]}; echo \$REPLY
    echo "$x <- main" >&\${$x[1]}
    read -r -u \${$x[0]}; echo \$REPLY
RUN
done

et ensuite

# ./coproc.sh 
declare -a COPROC0='([0]="21" [1]="16" [2]="23")'
declare -a COPROC1='([0]="24" [1]="19" [2]="26")'
declare -a COPROC2='([0]="27" [1]="22" [2]="29")'
declare -a COPROC3='([0]="30" [1]="25" [2]="32")'
declare -a COPROC4='([0]="33" [1]="28" [2]="35")'
declare -a COPROC5='([0]="36" [1]="31" [2]="38")'
coproc[0] -> main
COPROC0 <- main
coproc[1] -> main
COPROC1 <- main
coproc[2] -> main
COPROC2 <- main
coproc[3] -> main
COPROC3 <- main
coproc[4] -> main
COPROC4 <- main
coproc[5] -> main
COPROC5 <- main

Le <( :) ouvre un tube anonyme via la substitution de processus, qui meurt, mais le tube reste là parce que vous avez un handle sur lui. Je fais habituellement un sleep 1 au lieu de : parce que c'est un peu osé, et j'obtiendrais une erreur "fichier occupé" -- cela n'arrive jamais si une vraie commande est lancée (ex, command true )

"heredoc sourcing" :

. /dev/stdin <<EOF
[...]
EOF

Cela fonctionne sur tous les shells que j'ai essayés, y compris busybox/etc (initramfs). Je ne l'ai jamais vu faire avant, je l'ai découvert indépendamment en poussant, qui savait que source pouvait accepter des args ? Mais cela sert souvent comme une forme beaucoup plus facile à gérer de eval, si une telle chose existe.

3 votes

Pourquoi le vote négatif ... qu'importe si la question est ancienne ; elle est manifestement pertinente étant donné qu'il y a 11 autres réponses qui sont nulles. ces solutions sont, sans systemd, la manière idiomatique et acceptée de démoniser depuis 30 ans, pas des applications inutiles, par exemple nohup et al.

7 votes

Quelle que soit la qualité de votre réponse, il arrive que quelqu'un sur SO ne l'aime pas et la vote. Il est préférable de ne pas trop s'en inquiéter.

0 votes

Cette technique ne fonctionne pas lorsqu'on essaie de lancer un travail par programme via ssh, par exemple "$ ssh myhost "((exec sleep 30)&)"".

38voto

Brian Knoblauch Points 8747
nohup blah &

Remplacez le nom de votre processus par blah !

2 votes

Vous pouvez ajouter la redirection de la sortie standard et de l'erreur standard.

9 votes

Nohup redirige stdout et stderr vers nohup.out (ou nohup.out et nohup.err selon la version), donc à moins que vous exécutiez plusieurs commandes, ce n'est pas nécessaire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X