Sur Cygwin, je souhaite qu'un script Bash puisse:
La partie arrêt a été perplexe.
Actuellement, j'ai une solution boiteuse. Dans un shell, je lance ce qui suit pour créer un tunnel:
# Create the tunnel - this works! It runs forever, until the Shell is quit.
ssh -nNT -L 50000:localhost:3306 [email protected]
Puis, dans une autre fenêtre de Shell, je fais mon travail:
# Do some MySQL stuff over local port 50000 (which goes to remote port 3306)
Enfin, lorsque j'ai terminé, je ferme la première fenêtre Shell pour supprimer le tunnel.
Je voudrais faire tout cela dans un script comme:
# Create tunnel
# Do work
# Kill tunnel
Comment puis-je suivre le processus de tunnel pour savoir lequel tuer?
Vous pouvez le faire proprement avec une 'socket de contrôle' ssh. Pour parler à un processus SSH déjà en cours d'exécution et obtenir son pid, tuez-le, etc. Utilisez le 'socket de contrôle' (-M pour maître et -S pour socket) comme suit:
$ ssh -M -S my-ctrl-socket -fnNT -L 50000:localhost:3306 [email protected]
$ ssh -S my-ctrl-socket -O check [email protected]
Master running (pid=3517)
$ ssh -S my-ctrl-socket -O exit [email protected]
Exit request sent.
Notez que my-ctrl-socket sera un fichier créé.
J'ai reçu cette information de ne réponse très RTFM sur la liste de diffusion OpenSSH .
Vous pouvez indiquer à SSH de se fonder avec l'option -f mais vous n'obtiendrez pas le PID avec $ !. De plus, au lieu de laisser votre script dormir une quantité de temps arbitraire avant d'utiliser le tunnel, vous pouvez utiliser -o ExitOnForwardFailure = yes avec -f et SSH attendra que tous les transferts de ports distants soient correctement établis avant de se placer en arrière-plan. Vous pouvez grep la sortie de ps pour obtenir le PID. Par exemple, vous pouvez utiliser
...
ssh -Cfo ExitOnForwardFailure=yes -NL 9999:localhost:5900 $REMOTE_Host
PID=$(pgrep -f 'NL 9999:')
[ "$PID" ] || exit 1
...
et soyez sûr que vous obtenez le PID souhaité
ssh
de passer en arrière-plan avec &
et ne créez pas de shell de l’autre côté (ouvrez simplement le tunnel) avec un indicateur de ligne de commande (je vois que vous l’avez déjà fait avec -N
).PID=$!
kill $PID
EDIT: Fixe $? à $! et ajouté le &
Je préfère lancer un nouveau shell pour des tâches distinctes et j'utilise souvent la combinaison de commandes suivante:
$ Sudo bash; exit
ou parfois:
$ : > sensitive-temporary-data.txt; bash; rm -f sensitive-temporary-data.txt; exit
Ces commandes créent un shell imbriqué dans lequel je peux effectuer tout mon travail. Quand j'ai terminé, j'appuie sur CTRL-D et le parent Shell nettoie et quitte également. Vous pourriez facilement jeter bash;
dans votre script de tunnel ssh juste avant la partie kill
de sorte que, lorsque vous vous déconnectez du shell imbriqué, votre tunnel soit fermé:
#!/bin/bash
ssh -nNT ... &
PID=$!
bash
kill $PID
Une autre option potentielle - si vous pouvez installer le paquet expect, vous devriez être capable de scripter le tout. Quelques bons exemples ici: http://en.wikipedia.org/wiki/Expect
Vous pouvez lancer le ssh
avec un &
a la fin, pour le mettre en arrière-plan et saisir son identifiant lorsque vous le faites. Ensuite, il vous suffit de faire un kill
de cet identifiant lorsque vous avez terminé.