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.
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 surno
, 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 suryes
ou0
, 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 danssshd_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.
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
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!
J'ajoute à ControlPath
et ControlPersist
manière correcte, proposée par réponse de mur , je voudrais présenter une alternative:
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
Exécuter commande longue durée :
exec 8> >(exec ssh user@Host /bin/bash >$HOME/sshfifo
exec 9<$HOME/sshfifo
Alors maintenant tu n'as plus besoin du fifo
rm $HOME/sshfifo
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
}
Cela restera jusqu'à ce que vous fermiez explicitement cette connexion:
exec 8>&-
exec 9<&-
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
).
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 ...
Vous pouvez utiliser cat
pour concaténer tous les fichiers, puis les diriger vers ssh
.
cat command1 command2 command3 | ssh root@Host 'bash -s'