使用子进程在本地执行远程脚本 - 远程脚本使用来自〜/ .profile的变量

时间:2017-12-20 11:32:16

标签: python bash unix subprocess

我正在执行驻留在远程服务器上的脚本。 这个bash脚本使用了一个变量。 该变量在〜/ .profile中定义。 为此,我们说吧

$MYVAR=/a/b/c

所以在远程服务器上,甚至ssh到远程服务器,我执行

echo $MYVAR returns /a/b/c as you would expect.

但是如果我使用python子进程在本地执行远程脚本,脚本将失败。它失败,因为脚本使用$ MYVAR,因为soemthing不正确。

这是因为我通过SSH执行它,〜。/ profile不能被加载,而是使用其他一些配置文件。 见https://superuser.com/questions/207200/how-can-i-set-environment-variables-for-a-remote-rsync-process/207262#207262

这是从python脚本执行的命令

ssh = subprocess.Popen(['ssh', '%s' % env.host, 'cd /script/dir | ./myscript arg1 arg2'],shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

我的问题是如何在本地运行脚本,将ssh转移到远程,加载用户〜/ .profile然后执行bash脚本。

2 个答案:

答案 0 :(得分:1)

您可以使用paramiko模块从本地运行远程服务器上的脚本。

http://www.paramiko.org/

安装完成后,您可以运行命令,如下面的示例所示

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)

答案 1 :(得分:0)

最简单的解决方案是创建一种像这样的包装器脚本

#!/bin/bash
. /users/me/.profile

cd /dir/where/script/exists/

exec script LIVE "$@"

现在,然后在python脚本中创建一个方法,将包装脚本scp为tmp dir

scp wrapper user@remote:/tmp

现在问题中的ssh命令变为

subprocess.Popen(['ssh', '%s' % env.host, env.installPatch],shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

env.installPatch转换为:

cd /tmp; ./wrapper 'patch_name'

现在加载.profile并且补丁脚本具有正确的变量val。 使用exec我从补丁o / p返回所有输出并可以写入文件。

对我来说,这是最干净的解决方案。