Je voudrais exécuter et configurer un processus de la même manière vers un démon d'un script.
[.____] Mon shell est émulé de ZSH sous Cygwin et le démon est SFK , un serveur FTP de base.
Pour ce qui compte ici, le script startserv.sh
peut être rédigé comme suit:
#!/bin/sh
read -s -p "Enter Password: " pw
user=testuser
share=/fshare
cmd="sfk ftpserv -user=$user -pw=$pw -usedir $share=$share"
$cmd &
Après avoir exécuté le script startserv.sh
, ça arrête (se termine?) Sans montrer aucune invite, alors:
CTRL+C termine à la fois le script et le processus d'emploi de fond;
Frappe Enter Le script met fin au processus reste en arrière-plan.
Quoi qu'il en soit, je ne peux le voir que via ps
_ et pas jobs
, donc, lorsque je veux fermer le processus, je dois envoyer une brutale kill -9
signal, qui est quelque chose que j'aimerais éviter en faveur de CTRL+C.
Une alternative serait exécuter l'ensemble du script en arrière-plan. "Serait", mais la commande read
est impossible d'obtenir l'entrée de l'utilisateur si le script est exécuté comme startserv.sh &
.
Notez que j'ai besoin d'un serveur éphémère, pas d'un true Daemon : c'est-à-dire que je souhaite que le processus serveur fonctionne en arrière-plan, après la fin du script, Pour effectuer de simples tâches de shell interactifs (avec une machine à machine virtuelle), mais je n'ai pas besoin du processus pour survivre à la coquille; Par conséquent, Nohup
semble ne pas approprié.
Frappe Enter Le script met fin au processus reste en arrière-plan.
Presque! En fait, le script est déjà sorti au moment où vous appuyez sur Enter. Cependant, c'est ainsi que vous pouvez récupérer votre retour (car votre shell imprime son $PS1
encore une fois).
La raison pour laquelle frapper Ctrl + C se termine les deux, c'est parce que les deux d'entre eux sont liés. Lorsque vous exécutez votre script, votre shell initie un sous-vase dans lequel l'exécuter. Lorsque vous terminez ce sous-groupe, votre processus de référence décède, probablement à partir d'un signal SIGHUP
.
Utilisation Nohup
, vous pourrez peut-être vous débarrasser de ce petit inconvénient.
#!/bin/sh
read -s -p "Enter Password: " pw
user=testuser
share=/fshare
cmd="sfk ftpserv -user=$user -pw=$pw -usedir $share=$share"
Nohup $cmd &
disown
alternativeSi vous pouvez passer de /bin/sh
à /bin/bash
, vous pouvez essayer d'essayer de disown
aussi. Pour en savoir plus, il suffit de taper help disown
Dans une instance bash
.
disown -h $cmd &
Maintenant, quand il s'agit de tuer votre processus, vous pouvez parfaitement faire un "Ctrl + C"Utiliser kill
. N'envoyez pas un brutal SIGKILL
. Au lieu de cela, vous pouvez utiliser:
$ kill -2 [PID]
$ kill -15 [PID]
Qui enverra une belle SIGINT
(2) ou SIGTERM
(15) à votre processus. Vous pouvez également vouloir imprimer la valeur PID après le démarrage du processus:
...
Nohup $cmd &
echo $!
... ou même mieux, faites attendre le script pour un SIGINT
et le renvoyer au processus d'arrière-plan (((((((((cela conservera votre script au premier plan) := := :=:
#!/bin/sh
read -s -p "Enter Password: " pw
user=testuser
share=/fshare
cmd="sfk ftpserv -user=$user -pw=$pw -usedir $share=$share"
Nohup $cmd &
# Storing the background process' PID.
bg_pid=$!
# Trapping SIGINTs so we can send them back to $bg_pid.
trap "kill -2 $bg_pid" 2
# In the meantime, wait for $bg_pid to end.
wait $bg_pid
Si un SIGINT
ne suffit pas, utilisez simplement un SIGTERM
à la place (15):
trap "kill -15 $bg_pid" 2 15
De cette façon, lorsque votre script reçoit un SIGINT
(Ctrl + C, kill -2
) ou un SIGTERM
_ _ _ wait
ing pour le processus d'arrière-plan, cela relâchera simplement les signaux. Si ces signaux tuent l'instance sfk
, alors l'appel wait
_ sera renvoyé, terminant ainsi votre script aussi :)