Je veux pouvoir envoyer des signaux (SIGINT est le plus important) via ssh.
Cette commande:
ssh server "sleep 1000;echo f" > foo
va commencer à dormir sur le serveur et après 1000 secondes, il mettra 'f \ n' dans le fichier foo sur ma machine locale. Si j'appuie sur CTRL-C (c'est-à-dire que j'envoie SIGINT à ssh), cela tuera ssh, mais il ne tuera pas sleep sur le serveur distant. Je veux qu'il tue le sommeil sur le serveur distant.
J'ai donc essayé:
ssh server -t "sleep 1000;echo f" > foo
Mais si stdin n'est pas un terminal, j'obtiens cette erreur:
Pseudo-terminal will not be allocated because stdin is not a terminal.
puis SIGINT n'est toujours pas transmis.
J'ai donc essayé:
ssh server -t -t "sleep 1000;echo f" > output
Mais alors la sortie dans foo n'est pas 'f \ n' mais plutôt 'f \ r \ n' ce qui est désastreux dans ma situation (car ma sortie est des données binaires).
Dans ce qui précède, j'utilise "sleep 1000; echo f", mais en réalité qui est fourni par l'utilisateur, il peut donc contenir n'importe quoi. Cependant, si nous pouvons le faire fonctionner pour "sleep 1000; echo f", nous pouvons très probablement le faire fonctionner pour toutes les situations réalistes.
Je ne me soucie vraiment pas d'obtenir un pseudo-terminal à l'autre extrémité, mais je n'ai pas pu trouver d'autre moyen de faire en sorte que ssh transfère mon SIGINT.
Y a-t-il une autre façon?
Modifier:
L'utilisateur peut donner des commandes qui lisent des données binaires depuis stdin, telles que:
seq 1000 | gzip | ssh server "zcat|bzip2; sleep 1000" | bzcat > foo
L'utilisateur peut donner des commandes gourmandes en CPU, telles que:
ssh server "timeout 1000 burnP6"
Edit2:
La version qui semble fonctionner pour moi est:
your_preprocessing |
uuencode a | ssh -tt -oLogLevel=quiet server "stty isig -echoctl -echo ; uudecode -o - |
your_command |
uuencode a" | uudecode -o - |
your_postprocessing
Merci à digital_infinity de m'avoir pointé dans la bonne direction.
ssh
doit être plus compliquée que ce que vous montrez à titre d'exemples, car vous pouvez obtenir le comportement que vous souhaitez avec un simple réarrangement:sleep 1000 && ssh server "echo f" > foo
(Il doit l'être&&
, non;
, afin que la suppressionsleep
empêche l'ssh
exécution de la commande.) Si je avez raison, veuillez rendre vos exemples plus représentatifs de votre utilisation réelle, afin qu'une meilleure réponse puisse être donnée.Réponses:
Réponse courte:
et arrêtez le programme par CTRL + N.
Explication longue:
stty
optionintr
pour modifier votre serveur ou le caractère d'interruption local pour ne pas entrer en collision les uns avec les autres. Dans la commande ci-dessus, j'ai changé le caractère d'interruption du serveur en CTRL + N. Vous pouvez modifier votre caractère d'interruption local et laisser celui du serveur sans aucun changement.stty -echoctl
.stty isig
SIGINT
signaltrap '/bin/true' SIGINT
avec une instruction vide. Sans le piège, vous n'aurez aucune sortie après le signal SIGINT de votre côté.la source
seq 1000 | gzip | ssh -tt dell-test "zcat|bzip2" | bzcat > foo
ne fonctionne pas trop. Pour que cette commande fonctionne, nous devons la supprimer-tt
. Donc, l'allocation pseudo-terminale prend probablement une entrée de stdin(sleep 1; seq 1000 ) | gzip | uuencode bin | ssh -tt dell-test "stty isig intr ^N -echoctl -echo ; trap '/bin/true' SIGINT; sleep 1; uudecode -o /dev/stdout | zcat |bzip2 | uuencode bin2 " | uudecode -o /dev/stdout | bzcat >foo
. Bien que le caractère d'interruption ne fonctionne pas - nous avons besoin d'une méthode de transmission pour le caractère d'interruption lorsque stdin est occupé .J'ai essayé toutes les solutions et c'était la meilleure:
/programming/3235180/starting-a-process-over-ssh-using-bash-and-then-killing-it-on-sigint/25882610#25882610
la source
sleep
processus en cas de perte de connexion.sleep
ça, non? J'en ai ajouté quelques-unsdate >> /tmp/killed
après lecat
, mais cela n'a pas été déclenché. Y a-t-il un délai d'attente impliqué? J'utilise Zsh normalement, mais je l'ai également testé avec bash comme shell de connexion à distance.-o ServerAliveInterval=3 -o ServerAliveCountMax=2
permet de le détecter rapidement, mais y a-t-il quelque chose pour le côté serveur?Je pense que vous pouvez trouver le PID du processus que vous exécutez sur le serveur et envoyer un signal en utilisant une autre
ssh
commande (comme ceci:)ssh server "kill -2 PID"
.J'utilise cette méthode pour envoyer des signaux de reconfiguration à des applications fonctionnant sur une machine différente (mes applications attrapent SIGUSR1 et lisent un fichier de configuration). Dans mon cas, trouver un PID est facile, car j'ai des noms de processus uniques et je peux trouver le PID en envoyant une
ps
demande viassh
.la source
La solution est devenue http://www.gnu.org/software/parallel/parallel_design.html#Remote-Ctrl-C-and-standard-error-stderr
la source
----- command.sh
----- sur le terminal local
la source