Comment écrire un script bash, qui se connecte à une autre machine pour faire des choses?

11

Est-il possible d'écrire un script bash,

  1. serait démarré à partir de la machine A, se connecte à une autre machine B par ssh (les deux machines A et B seraient des machines Linux),
  2. copie certains fichiers sur la machine B
  3. exécute un script python un script python donné sur ces machines.
  4. transfère les résultats à la machine A
  5. se déconnecte de la machine B.

Est-ce techniquement faisable?

Aufwind
la source

Réponses:

15

Bien sûr, c'est faisable:

scp file user@host:
ssh user@host path_to_script
scp user@host:file_to_copy ./

et c'est tout...

Mais il y a un problème: le mot de passe vous sera demandé trois fois. Pour éviter cela, vous pouvez générer des clés ssh et autoriser les utilisateurs par ces clés.

Pour générer des clés ssh exécutées ssh-keygen -t rsa, répondez aux questions et copiez la clé publique sur l'hôte distant (machine B) dans le ~/.ssh/authorized_keysfichier. La clé privée doit être enregistrée ~/.ssh/id_rsasur la machine locale (A).

pbm
la source
Si les clés publiques ne sont pas une option, vous pourriez faire quelque chose de grossier pour minimiser les invites de mot de passe commecat file | ssh user@host 'cat > /destination/of/file; /path/to/script &>/dev/null; cat results' > /destination/of/results
Patrick
Si vous souhaitez utiliser le mot de passe, vous pouvez toujours utiliser le pool de connexions d'OpenSSH en définissant ControlMaster=yeset ControlPath=/path/to/socketfile, puis démarrer une connexion ssh avec -fpour exécuter un ssh en arrière-plan. Dites à toutes les connexions SSH suivantes d'utiliser le même fichier socket.
jsbillings
4

Il est possible de tout faire en une seule sshconnexion / session:

ssh user@host "cat > remote_dst; command; cat remote_src" < local_src > local_dst

Cette:

  1. Copies local_srcvers remote_dst,
  2. Exécute command,
  3. Copies remote_srcvers local_dst.

Mais si on commandécrit dessus stdout, le résultat sera également au rendez-vous local_dst. Si commandlit l'entrée de stdin, il recevra et EOF.

jfg956
la source
3

Bien que vous puissiez le faire dans une seule session ssh, il est un peu difficile de combiner la copie de fichiers avec des commandes en cours d'exécution.

La façon la plus simple de s'attaquer à cette tâche consiste à exécuter des sessions SSH distinctes pour les trois opérations:

rsync -a inputs/ machineB:inputs/
ssh machineB 'some command -i inputs -o outputs'
rsync -a machineB:outputs/ outputs/

Cela nécessite une authentification trois fois sur machineB. La méthode recommandée pour éviter de s'authentifier plusieurs fois consiste à utiliser la fonction de partage de connexion dans les versions modernes d'OpenSSH: démarrez une connexion principale à B une fois pour toutes et laissez SSH se superposer automatiquement à cette connexion principale. Ajoutez ControlMaster autoune ControlPathligne à votre~/.ssh/config , puis démarrez une connexion principale en arrière-plan, puis effectuez vos tâches.

ssh -fN machineB                         # start a master connection in the background
# Subsequent connections will be slaves to the existing master connection
rsync -a inputs/ machineB:inputs/
ssh machineB 'some command -i inputs -o outputs'
rsync -a machineB:outputs/ outputs/

Plutôt que d'utiliser scp ou rsync pour copier des fichiers, il peut être plus facile de monter le système de fichiers distant sous SSHFS . Soit dit en passant, cela permettra de configurer une connexion principale (en supposant que vous avez configuré votre connexion ~/.ssh/configcomme indiqué ci-dessus).

mkdir /net/machineB
sshfs machineB: /net/machineB
cp -Rp inputs /net/machineB/
ssh machibeB 'some command -i inputs -o outputs'
cp -Rp /net/machineB/outputs .
Gilles 'SO- arrête d'être méchant'
la source