J’exécute un script qui réside sur le serveur distant. Ce script bash utilise une variable. Cette variable est définie dans ~ / .profile. A cette fin, disons le
$MYVAR=/a/b/c
Donc, sur le serveur distant, ou même ssh à distance et j’exécute
echo $MYVAR returns /a/b/c as you would expect.
Mais si j’exécute le script distant localement en utilisant le sous-processus python, le script échoue. Il échoue car le script utilise le $ MYVAR qui se traduit par une erreur incorrecte.
C’est parce que je l’exécute via SSH, le profil ~. / Ne doit pas être chargé et à la place il utilise un autre profil. voir ici https://superuser.com/questions/207200/how-can-i-set-environment-variables-for-a-remote-rsync-process/207262#207262
Voici la commande exécutée à partir d’un script python
ssh = subprocess.Popen(['ssh', '%s' % env.host, 'cd /script/dir | ./myscript arg1 arg2'],shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
Ma question est de savoir comment puis-je exécuter un script localement, qui sera ssh à distance, charger les utilisateurs ~ / .profile puis exécuter un script bash.
Vous pouvez utiliser le module paramiko pour exécuter les scripts sur le serveur distant à partir du local.
Une fois installé, vous pouvez exécuter la commande comme indiqué dans l’exemple ci-dessous
import paramiko command=" 'ssh', '%s' % env.host, 'cd /script/dir | ./myscript arg1 arg2' " ssh=paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.connect('192.18.1.26',port=22,username='root',password='defassult') #This will connect to remote server stdin,stdout,stderr=ssh.exec_command(command) #This will execute the command on remote server output=stdout.readlines() print '\n'.join(output)
La solution la plus simple pour cela était de créer une sorte de script de wrapper comme
#!/bin/bash . /users/me/.profile cd /dir/where/script/exists/ exec script LIVE "$@"
Alors maintenant, créez une méthode dans le script python pour scp le script wrapper vers tmp dir
scp wrapper user@remote:/tmp
Maintenant, la commande ssh dans la question devient
subprocess.Popen(['ssh', '%s' % env.host, env.installPatch],shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
env.installPatch se traduit par:
cd /tmp; ./wrapper 'patch_name'
Maintenant, le fichier .profile est chargé et le script de correctif a les variables correctes. En utilisant exec, je récupère toute la sortie du patch o / p et je peux écrire dans un fichier.
C’était la solution la plus propre pour mon cas.