J'ai une machine locale qui est censée créer une session SSH vers une master
machine distante , puis une autre session SSH interne de la master
à chacun de certaines télécommandes slaves
, puis exécuter 2 commandes, c'est-à-dire supprimer un répertoire spécifique et le recréer.
Notez que la machine locale a SSH sans mot de passe pour le maître et le maître a SSH sans mot de passe pour les esclaves. De plus, tous les noms d'hôtes sont connus sur .ssh/config
les machines locales / maîtres et les noms d'hôtes des esclaves sont slaves.txt
localement et je les lis à partir de là.
Donc, ce que je fais et travaille est le suivant:
username="ubuntu"
masterHostname="myMaster"
while read line
do
#Remove previous folders and create new ones.
ssh -n $username@$masterHostname "ssh -t -t $username@$line "rm -rf Input Output Partition""
ssh -n $username@$masterHostname "ssh -t -t $username@$line "mkdir -p EC2_WORKSPACE/$project Input Output Partition""
#Update changed files...
ssh -n $username@$masterHostname "ssh -t -t $username@$line "rsync --delete -avzh /EC2_NFS/$project/* EC2_WORKSPACE/$project""
done < slaves.txt
Ce cluster est sur Amazon EC2 et j'ai remarqué qu'il y a 6 sessions SSH créées à chaque itération ce qui induit un retard important. Je voudrais combiner ces 3 commandes en 1 pour obtenir moins de connexions SSH. J'ai donc essayé de combiner les 2 premières commandes en
ssh -n $username@$masterHostname "ssh -t -t $username@$line "rm -rf Input Output Partition && mkdir -p EC2_WORKSPACE/$project Input Output Partition""
Mais cela ne fonctionne pas comme prévu. Il semble exécuter le premier ( rm -rf Input Output Partition
) puis quitte la session et continue. Que puis-je faire?
la source
-J
option qui définirait votre hôte de saut.Réponses:
Considérez que
&&
c'est un opérateur logique. Cela ne signifie pas "exécuter également cette commande", cela signifie "exécuter cette commande si l'autre réussit".Cela signifie que si la
rm
commande échoue (ce qui se produira si l'un des trois répertoires n'existe pas), lemkdir
ne sera pas exécuté. Cela ne ressemble pas au comportement que vous souhaitez; si les répertoires n'existent pas, c'est probablement bien de les créer.Utilisation
;
Le point
;
- virgule est utilisé pour séparer les commandes. Les commandes sont exécutées séquentiellement, en attendant chacune avant de passer à la suivante, mais leur succès ou leur échec n'a aucun impact les uns sur les autres.Échapper aux citations intérieures
Les citations à l'intérieur d'autres citations doivent être échappées, sinon vous créez un point final et un point de départ supplémentaires. Votre commande:
Devient:
Votre commande actuelle, en raison du manque de guillemets échappés, devrait s'exécuter:
si cela réussit:
Vous remarquerez que la coloration syntaxique montre la commande entière en rouge ici, ce qui signifie que la commande entière est la chaîne transmise à ssh. Vérifiez votre machine locale; vous pouvez avoir les répertoires
Input
Output
etPartition
où vous l'exécutiez.la source
&
commandes s'exécutent en arrière-plan, ce qui signifie qu'elles ne seront pas attendues pour terminer avant de passer à la suivante.Vous pouvez toujours définir dans votre Jumpbox Multiplexage dans OpenSSH
Pour cela, faites en
/etc/ssh/ssh_config
:De cette façon, toutes les connexions consécutives établies au même serveur dans les 30 minutes suivantes seront effectuées en réutilisant la connexion ssh précédente.
Vous pouvez également le définir pour une machine ou un groupe de machines. Tiré du lien fourni.
la source
/tmp/
.man ssh
,ControlPath
,ControlMaster
etControlPersist
sont des options valides pour passer unessh
commande à l' aide-o
. Cela pourrait être un cas d'utilisation encore plus précis, configurer le multiplexage dans le premierssh
du script et le recycler pour les autres, mais sinon, évitez la pénalité de performance. Je me demande ce que la référence du multiplexage VS n'est pas pour 3 connexions SSH, étant donné que "Il y a aussi un retard important lors de l'ouverture d'une nouvelle connexion"Vous pouvez mettre toutes vos commandes dans un script séparé sur votre serveur "maître".
Script maître
Ensuite, dans votre script ssh, appelez-le comme ceci: Script SSH
OU si tous les fichiers doivent se trouver sur la machine initiale, vous pouvez faire quelque chose comme ceci:
script1
script2
script ssh
la source
Il y a quelque temps, j'ai eu l'occasion d'utiliser des sockets de contrôle comme les autres réponses le recommandent (cette réponse est essentiellement une combinaison de l'utilisation de sockets de contrôle comme cette réponse et de scripts comme cette réponse ).
Le cas d'utilisation était un hack:
authorized_keys
l'utilisateur cible était écrasé périodiquement par une tâche planifiée et je voulais tester rapidement les choses sans passer par la paperasserie nécessaire pour ajouter quelque chose à ce fichier. J'ai donc configuré une boucle while qui a ajouté la clé à ce fichier si nécessaire, exécuté mon test et annulé la boucle. Cependant, il y aurait une petite fenêtre où la tâche planifiée écraserait le fichier et ma boucle serait toujourssleep
en cours. Donc, configurer un socket de contrôle au début permettrait à mon script SSH plus tard sans problème:Où
setup-ssh.sh
est:Et
.ssh-config
:Et
run-test.sh
:La séquence se déroule comme suit:
setup-ssh.sh
.setup-ssh.sh
occupé-boucle les serveurs jusqu'à ce que tous aient une configuration de socket de contrôle. Lehosts
fichier répertorie simplement les noms d'hôte du serveur un par ligne.${CONFIG_DIR}/scripts/.ssh-config
, à moins que je ne spécifie ce fichier à l'aide-F
, les connexions SSH ne l'utiliseront pas. Cela me permet donc d'utiliser la prise de contrôle uniquement là où j'en ai besoin en utilisant l'F
option.xargs
pour répartir la charge de travail sur les serveurs, en démarrant de nouveaux travaux dès la fin de ceux-ci.la source