【问题标题】:Executing remote script locally using subprocess - Remote script uses vars from ~/.profile使用子进程在本地执行远程脚本 - 远程脚本使用 ~/.profile 中的变量
【发布时间】:2018-06-02 22:56:33
【问题描述】:

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

$MYVAR=/a/b/c

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

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

但是如果我使用 python 子进程在本地执行远程脚本,脚本就会失败。它失败了,因为脚本使用了 $MYVAR,它被翻译为一些不正确的东西。

这是因为我是通过 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 脚本。

【问题讨论】:

  • 不知道$MYVAR 是如何在您的代码中使用的,是在./myscript 中吗?
  • cd something | somecommand 没有任何用处,因为cd 不会在标准输出上产生任何有用的信息。您实际上想要完成什么?
  • 您在寻找['ssh', 'remote', 'cd dir; myvar="{}" somecommand arg1 arg2'.format(shlex.quote(os.environ['MYVAR']))吗?
  • 我想 ssh 到远程,将目录更改为脚本所在的位置。然后运行脚本。 $MYVAR 根本没有在我的代码中使用。远程脚本使用它。该远程脚本退出是因为 $MYVAR 不是它应该是的。奇怪的是(无论如何对我来说)是当您在远程机器上运行 echo $MYVAR 时,它会返回预期的内容。那么它从哪里获得其他价值。那是我不明白的。
  • @Nanotron 试试这个superuser.com/questions/306530/…

标签: python bash unix subprocess


【解决方案1】:

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

#!/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 已加载并且补丁脚本具有正确的变量 vals。 通过使用 exec,我可以从补丁 o/p 中获取所有输出,并且可以写入文件。

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

【讨论】:

    【解决方案2】:

    您可以使用 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)
    

    【讨论】:

    • 嗨,是的,我知道有可用的模块,但我试图让其他人使用这个脚本尽可能简单。即为此目的,只能使用标准库模块。
    猜你喜欢
    • 2017-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多