Fin de la session SSH exécutée par bash script

j'ai un script que je peux exécuter localement pour démarrer un serveur à distance:

#!/bin/bash
ssh user@host.com <<EOF
  nohup /path/to/run.sh &
EOF
echo 'done'

après avoir couru nohup, il est pendu. Je dois frapper ctrl-c pour quitter le script.

j'ai essayé d'ajouter une sortie explicite à la fin du doc ici et en utilisant l'argument"- t " pour ssh. Aucun ne fonctionne. Comment puis-je faire sortir ce script immédiatement?

EDIT: le client est OSX 10.6, le serveur est Ubuntu.

18
demandé sur mahemoff 2011-08-17 01:44:49

4 réponses

je pense que le problème est que nohup ne peut pas rediriger la sortie quand vous arrivez de ssh, il redirige seulement vers nohup.quand il pense qu'il est connecté à un terminal, et je le STDIN override que vous avez empêchera cela, même avec -t .

une solution de rechange pourrait être de rediriger la sortie vous - même, alors le client ssh peut se déconnecter-il n'attend pas que le flux se ferme. Quelque chose comme:

nohup /path/to/run.sh > run.log &

pour moi dans un test simple Se connecter à un serveur Ubuntu à partir D'un client OS X.)

16
répondu martin clayton 2018-09-04 22:48:58

le problème pourrait être cela ...

... ssh is respecting the POSIX standard when not closing the session 
if a process is still attached to the tty.

par conséquent, une solution pourrait être de détacher la commande stdin de la commande nohup de l'ATS:

nohup /path/to/run.sh </dev/null &

Voir: SSH se Bloque Sur la Sortie Lors de l'Utilisation de nohup

une autre approche pourrait être d'utiliser ssh -t -t pour forcer l'attribution de pseudo-ATS même si stdin n'est pas un terminal.

man ssh | less -Ip 'multiple -t'

ssh -t -t user@host.com <<EOF
  nohup /path/to/run.sh &
EOF

voir: BASH frayer shell interne est exécuté pour le SSH et continuer avec le programme

8
répondu chad 2017-05-23 12:02:08

rediriger le stdin de l'hôte distant à partir d'un document ici en invoquant ssh sans commande explicite conduit au message: Pseudo-terminal will not be allocated because stdin is not a terminal.

Pour éviter ce message soit utiliser ssh 's -T commutateur de dire à l'hôte distant n'est pas nécessaire d'attribuer un pseudo-terminal ou explicitement spécifier une commande (comme /bin/sh ) pour l'hôte distant pour exécuter les commandes fournies par le document.

si une commande explicite est donnée à ssh , la valeur par défaut est de fournir no shell de connexion sous la forme d'un pseudo-terminal, I. E. il n'y aura pas de session de connexion normale lorsqu'une commande est spécifiée (voir man ssh ).

sans la commande ssh , par contre, la valeur par défaut est de créer un pseudo-tty pour une session de connexion interactive sur l'hôte distant.

- ssh user@host.com <<EOF
+ ssh -T user@host.com <<EOF
+ ssh user@host.com /bin/bash <<EOF

comme un règle, ssh -t ou même ssh -t -t ne doit être utilisé que si il y a des commandes qui s'attendent à ce que stdin / stdout soit un terminal (comme top ou vim ) ou s'il est nécessaire de tuer le shell distant et ses enfants lorsque la commande client ssh termine l'exécution (voir: la commande ssh continue de manière inattendue sur un autre système après que ssh termine ).

autant que je sache, la seule façon de combiner un ssh la commande qui n'affecte pas un pseudo-tty et une commande nohup qui écrit nohup.out sur l'hôte distant est de laisser la commande nohup s'exécuter dans un pseudo-terminal et non créé par le mécanisme ssh . Cela peut être fait avec la commande script , par exemple, et évitera le message tcgetattr: Inappropriate ioctl for device .

#!/bin/bash
ssh localhost /bin/sh <<EOF
  #0<&-  script -q /dev/null nohup sleep 10 1>&- &
  #0<&- script -q -c "nohup sh -c 'date; sleep 10 1>&- &'" /dev/null  # Linux
  0<&- script -q /dev/null nohup sh -c 'date; sleep 10 1>&- &'        # FreeBSD, Mac OS X
  cat nohup.out
  exit 0
EOF
echo 'done'
exit 0
2
répondu tarox 2017-04-13 12:36:27

, Vous devez ajouter un exit 0 à la fin.

1
répondu jschorr 2018-09-04 23:47:15