web-dev-qa-db-fra.com

"Stocker" une session SSH distante?

J'essaie de les faire dans un script. Je dois exécuter certaines commandes sur un hôte distant. Actuellement, je fais ceci:

ssh root@Host 'bash -s' < command1
ssh root@Host 'bash -s' < command2
ssh root@Host 'bash -s' < command3

Cependant, cela signifie que je dois me connecter au serveur à plusieurs reprises, ce qui augmente beaucoup de temps entre le traitement des commandes. Je cherche quelque chose comme ça:

varSession=$(ssh root@Host 'bash -s')
varSeesion < command1
varSeesion < command2
varSeesion < command3

Encore une fois, je dois exécuter ces commandes via un script. J'ai jeté un œil à screen mais je ne suis pas sûr qu'il puisse être utilisé dans un script.

12
SayantanRC

Vous pouvez utiliser un ControlMaster et ControlPersist pour permettre à une connexion de persister après la fin de la commande:

Lorsqu'il est utilisé conjointement avec ControlMaster, spécifie que la connexion principale doit rester ouverte en arrière-plan (en attente de futures connexions client) après la fermeture de la connexion client initiale. S'il est défini sur no, la connexion principale ne sera pas placée en arrière-plan et se fermera dès que la connexion client initiale sera fermée. Si elle est définie sur yes ou 0, La connexion principale restera en arrière-plan indéfiniment (jusqu'à ce qu'elle soit interrompue ou fermée via un mécanisme tel que "ssh -O exit"). Si elle est définie sur une heure en secondes ou sur une heure dans l'un des formats documentés dans sshd_config(5), la connexion principale en arrière-plan se terminera automatiquement une fois qu'elle sera restée inactive (sans connexion client) pendant la durée spécifiée.

Ainsi, la première commande SSH configurera un fichier de contrôle pour la connexion, et les deux autres réutiliseront cette connexion via ce fichier de contrôle. Votre ~/.ssh/config Devrait avoir quelque chose comme:

Host host
    User root
    ControlMaster auto
    ControlPath /tmp/ssh-control-%C
    ControlPersist 30   # or some safe timeout

Et votre script n'aura pas besoin d'autres modifications.

29
muru

Vous pouvez prendre un indice d'un question similaire sur StackOverflow et utiliser un bash Document ici :

ssh root@Host 'bash -s' << EOF
  command1
  command2
  command3
EOF
7
Twinkles

Vous pouvez utiliser le script expect. Il peut automatiser la connexion ssh et exécuter des commandes sur la machine distante. Ce code devrait nous éclairer sur l'automatisation de la connexion ssh.

vous cherchez quelque chose comme ça. stocker le code suivant dans un fichier foo.expect

#login to the remote machine
spawn ssh username@hostname
expect "?assword" { send "yourpassword\r"}

#execute the required commands; following demonstration uses echo command
expect "$ " {send "echo The falcon has landed\r"}
expect "$ " {send "echo The falcons have landed\r"}
expect "$ " {send "echo Will the BFR? land? \r"}

#exit from the remote machine
expect "$ " {send "exit\r"}

exécutez-le comme expect foo.expect

Vous devez vous attendre à ce que l'application exécute ce script. Il peut être installé avec la commande apt-get install expect

Ce livre vous aidera à explorer le script attendu. Bonne écriture!

4
daedalus_hamlet

Descripteur de fichier indépendant pour un ou plusieurs [~ # ~] ssh [~ # ~] connexions

J'ajoute à ControlPath et ControlPersist manière correcte, proposée par réponse de mur , je voudrais présenter une alternative:

Méthode

  1. Créez un fifo que vous utiliserez pour les sorties de ssh

    Vous devez créer ce fichier dans un chemin que vous êtes sûr

    mkfifo $HOME/sshfifo
    
  2. Exécuter commande longue durée :

    exec 8> >(exec ssh user@Host /bin/bash >$HOME/sshfifo
    exec 9<$HOME/sshfifo
    
  3. Alors maintenant tu n'as plus besoin du fifo

    rm $HOME/sshfifo
    
  4. Vous êtes maintenant prêt à envoyer et à recevoir des commandes de votre connexion:

    echo >&8 uptime
    while read -t .002 -r -u 9 answer;do echo "$answer";done
    

    Nota: 0.002 seconds peut être insuffisant en cas de mauvaise connexion Internet ... Le délai peut être inutile en fonction du type de demandes. Tout cela pourrait être adapté au type de dialogue à suivre.

    Etc...

    myremote() {
        echo "$@" >&8
        while IFS= read -t .02 -r -u 9 answer;do
             echo "$answer"
        done
    }
    
  5. Cela restera jusqu'à ce que vous fermiez explicitement cette connexion:

    exec 8>&-
    exec 9<&-
    

Plus loin

Ce n'est pas parfait. Vous pourriez

  • Lier [~ # ~] stderr [~ # ~] aussi, avec un deuxième fifo

    mkfifo $HOME/sshfifo{out,err}
    exec 8> >(exec ssh user@Host /bin/bash >$HOME/sshfifoout 2>$HOME/sshfifoerr)
    exec 9<$HOME/sshfifoout
    exec 10<$HOME/sshfifoerr
    rm $HOME/sshfifo{out,err}
    
  • Utilisez bash interactif, puis réduisez le délai d'attente

    mkfifo $HOME/sshfifo{out,err}
    exec 8> >(exec ssh -tT user@Host /bin/bash -i >$HOME/sshfifoout 2>$HOME/sshfifoerr)
    exec 9<$HOME/sshfifoout
    exec 10<$HOME/sshfifoerr
    rm $HOME/sshfifo{out,err}
    echo >&8 'set -i;PS1="ReAdY aS BoUnD\\n"'
    while IFS= read -d '' -rn 1 -t .02 -u 9 foo;do echo -n "$foo";done
    while IFS= read -d '' -rn 1 -t .02 -u 10 foo;do echo -n "$foo";done
    

    ... puis à regarder /^ReAdY aS BoUnD$/ de fd/10 comme marqueur pour la fin de l'exécution de la dernière commande , vous pouvez éviter le délai d'attente pour STDERR (-u 10), puis réduisez timemout pour STDOUT (-u 9 -t .002).

Et à partir de là

Il est même possible d'ouvrir plusieurs connexions à utiliser ensemble

mkfifo $HOME/sshfifo
exec 8> >(exec ssh user1@hostA /bin/bash >$HOME/sshfifo 2>&1)
exec 9<$HOME/sshfifo
rm $HOME/sshfifo

mkfifo $HOME/sshfifo
exec 11> >(exec ssh user2@hostB /bin/bash >$HOME/sshfifo 2>&1)
exec 12<$HOME/sshfifo
rm $HOME/sshfifo

Alors

tee <<<uptime /dev/fd/8 >&11
read -u  9 -t .02 ansA
read -u 12 -t .02 ansB

d'envoyer la même commande simultanément aux deux extrémités ...

2
F. Hauri

Vous pouvez utiliser cat pour concaténer tous les fichiers, puis les diriger vers ssh.

cat command1 command2 command3 | ssh root@Host 'bash -s'
1
Barmar