web-dev-qa-db-fra.com

Suspendre un script en cours d'exécution dans le terminal Mac, puis reprendre plus tard

Comment puis-je suspendre (pas arrêter) un script en cours d'exécution à partir de Terminal dans OSX, pour le reprendre plus tard à partir du moment où il s'est arrêté?

20
Jikku Jose

Pour compléter les réponses utiles de @devnull et @ DavidW:
Voici fonctions pratiques pour suspendre (mettre en pause)/reprendre un script par son nom, à partir de tout Shell ( pas seulement celui qui a commencé le script):

Passez le (s) nom (s) de fichier du script ( sans chemin):

suspend-script someScript ...

et ensuite:

resume-script someScript ...

Mise à jour: Ajout d'une fonction supplémentaire pour tuer un script par son nom: kill-script someScript ...

  • Fonctionne avec des scripts exécutés par bash ou sh (qui est en fait juste un alias bash sur OSX).
  • Si plusieurs instances d'un script sont en cours d'exécution, seule la dernière démarrée est ciblée.
  • Le code de sortie sera différent de zéro en cas d'échec (y compris la non-recherche d'un script en cours d'exécution par le nom donné).
  • suspend-script et resume-script: si un processus de script est déjà dans l'état souhaité, aucune opération n'est effectuée (et aucune erreur n'est signalée).

Fonctions (par exemple, placez-les dans ~/.bash_profile):

suspend-script() {
  [[ -z $1 || $1 == '-h' || $1 == '--help' ]] && { echo "Usage: $FUNCNAME scriptFileName ..."$'\n'"Suspends the specified bash/sh script(s)."; return $(( ${#1} == 0 )); }
  local ec=0
  for p in "$@"; do
    pkill -STOP -nf '/?(bash|sh)[ ]+(.*/)?'"$p"'( |$)' \
      && echo "'$1' suspended." \
      || { ec=$?; echo "ERROR: bash/sh script process not found: '$p'" 1>&2; }
  done
  return $ec
}

resume-script() {
  [[ -z $1 || $1 == '-h' || $1 == '--help' ]] && { echo "Usage: $FUNCNAME scriptFileName ..."$'\n'"Resumes the specified bash/sh script(s)."; return $(( ${#1} == 0 )); }
  local ec=0
  for p in "$@"; do
    pkill -CONT -nf '/?(bash|sh)[ ]+(.*/)?'"$p"'( |$)' \
     && echo "'$1' resumed." \
     || { ec=$?; echo "ERROR: bash/sh script process not found: '$p'" 1>&2; }
  done
  return $ec
}

kill-script() {
  [[ -z $1 || $1 == '-h' || $1 == '--help' ]] && { echo "Usage: $FUNCNAME scriptFileName ..."$'\n'"Kills the specified bash/sh script(s)."; return $(( ${#1} == 0 )); }
  local ec=0
  for p in "$@"; do
    pkill -nf '/?(bash|sh)[ ]+(.*/)?'"$p"'( |$)' \
     && echo "'$1' killed." \
     || { ec=$?; echo "ERROR: bash/sh script process not found: '$p'" 1>&2; }
  done
  return $ec
}
3
mklement0

Si vous utilisez BASH comme shell (qui est le shell par défaut sur un Mac), vous pouvez utiliser les capacités intégrées de job control de BASH.

Si le script s'exécute au premier plan de votre terminal, vous pouvez appuyer sur Control-Z pour mettre le script en pause. Cela va suspendre l'exécution du script.

Pour le redémarrer, tapez jobs et vous verrez le job suspendu répertorié ici. Tapez fg ou plus spécifique fg %xx est le numéro du travail suspendu .

$ test.pl   # Test script (prints out Foo every two seconds
Foo!
Foo!
^Z
$  # Job has been suspended
$ jobs
[1] + Stopped                  ./test.pl
$ fg %1  #Restarts Job #1
Foo!

La clé Control-Z qui suspend le travail est la valeur par défaut, mais pourrait être modifiée. stty peut changer cela et vous montrera la valeur par défaut actuelle:

$ stty -a     
speed 9600 baud; 40 rows; 120 columns;
lflags: icanon isig iexten echo echoe -echok echoke -echonl echoctl
        -echoprt -altwerase -noflsh -tostop -flusho pendin -nokerninfo
        -extproc
iflags: -istrip icrnl -inlcr -igncr ixon -ixoff ixany imaxbel iutf8
        -ignbrk brkint -inpck -ignpar -parmrk
oflags: opost onlcr -oxtabs -onocr -onlret
cflags: cread cs8 -parenb -parodd hupcl -clocal -cstopb -crtscts -dsrflow
        -dtrflow -mdmbuf
cchars: discard = ^O; dsusp = ^Y; eof = ^D; eol = <undef>;
        eol2 = <undef>; erase = ^H; intr = ^C; kill = ^U; lnext = ^V;
        min = 1; quit = ^\; reprint = ^R; start = ^Q; status = ^T;
        stop = ^S; susp = ^Z; time = 0; werase = ^W;

Vous pouvez voir que la toute dernière ligne contient susp = ^Z. C'est la clé qui va suspendre votre script. Dans ce cas, c'est Control-Z .

Vous pouvez également utiliser la commande bg pour exécuter une exécution job suspendue en arrière-plan. Toutefois, ce travail d'arrière-plan se terminera lorsque vous fermerez la fenêtre Shell/Terminal, sauf si vous aviez ajouté Nohup au début de la commande.

43
David W.

Recherchez l'ID de processus du script en cours d'exécution.

Pour arrêter (ou ce que vous appelez pause) le script, dites:

kill -SIGSTOP PID

Pour reprendre le processus arrêté (ou en pause), dites:

kill -SIGCONT PID

(où PID fait référence à l'ID de processus numérique.)

9
devnull

echo Press any key to continue... read blah

Alors ne faites rien avec la variable. C'est aussi proche de la fonctionnalité pause que j'ai utilisée dans les scripts batch DOS que j'ai rencontrée.

1