在远程服务器上运行本地 python 脚本

Posted

技术标签:

【中文标题】在远程服务器上运行本地 python 脚本【英文标题】:Run local python script on remote server 【发布时间】:2013-12-28 05:48:05 【问题描述】:

我正在调试一些必须在我的虚拟机上运行的 python 脚本。而且,我更喜欢在本地(在虚拟机之外)编辑脚本。所以我发现每次将scp 修改脚本到虚拟机都是乏味。任何人都可以提出一些有效的方法吗?

特别是,我想知道是否可以在远程 PVM 上执行 python 脚本。类似的东西:

python --remote user@192.168.1.101 hello.py //**FAKED**, served to explain ONLY

【问题讨论】:

【参考方案1】:

你可以通过 ssh 来实现。

ssh user@192.168.1.101 "python ./hello.py"

您还可以使用文本编辑器或 X11 转发在 ssh 中编辑脚本。

【讨论】:

这会在远程服务器上执行一个 remote python 脚本。据我了解,作者希望在远程服务器上执行 local python 脚本。 是的,你是对的。我建议也直接在远程机器上通过 ssh 进行编辑,以避免“上传阶段”。实际上,您可以在一行中上传并执行文件(例如unix.stackexchange.com/a/57809)。但那个解决方案对我来说有点脏......【参考方案2】:

可以使用 ssh。 Python 接受连字符(-)作为参数来执行标准输入,

cat hello.py | ssh user@192.168.1.101 python -

运行 python --help 了解更多信息。

【讨论】:

如果代码在子文件夹中有子模块怎么办? @Pyaping cat hello.py | ssh user@192.168.1.101 python - arg1 arg2 arg3 为我工作 如果你使用cat a_single_file |,那么你做错了 如果那个python本地包含其他python模块就不行了。【参考方案3】:

虽然这个问题不是很新并且已经选择了答案,但我想分享另一种不错的方法。

使用paramiko 库 - SSH2 的纯 Python 实现 - 您的 Python 脚本可以通过 SSH 连接到远程主机,将自身(!)复制到该主机,然后在远程主机上执行该复制。远程进程的标准输入、标准输出和标准错误将在您的本地运行脚本上可用。所以这个解决方案几乎独立于 IDE。

在我的本地机器上,我使用命令行参数“deploy”运行脚本,这会触发远程执行。如果没有这样的参数,将运行用于远程主机的实际代码。

import sys
import os

def main():
    print os.name

if __name__ == '__main__':
    try:
        if sys.argv[1] == 'deploy':
            import paramiko

            # Connect to remote host
            client = paramiko.SSHClient()
            client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            client.connect('remote_hostname_or_IP', username='john', password='secret')

            # Setup sftp connection and transmit this script
            sftp = client.open_sftp()
            sftp.put(__file__, '/tmp/myscript.py')
            sftp.close()

            # Run the transmitted script remotely without args and show its output.
            # SSHClient.exec_command() returns the tuple (stdin,stdout,stderr)
            stdout = client.exec_command('python /tmp/myscript.py')[1]
            for line in stdout:
                # Process each line in the remote output
                print line

            client.close()
            sys.exit(0)
    except IndexError:
        pass

    # No cmd-line args provided, run script normally
    main()

为了简化这个例子,省略了异常处理。在具有多个脚本文件的项目中,您可能必须将所有这些文件(和其他依赖项)放在远程主机上。

【讨论】:

我可以将这个构造也用作with open paramiko.SSHClien() ... 以避免忘记close()吗? 检查 len(sys.argv) > 1,否则远程脚本会崩溃。此外,您在遥控器上的 bashrc(或 shell 初始配置)不得在标准输出(bash 中的回显)上包含任何打印内容。【参考方案4】:

在使用 Paramiko 之前,我必须这样做,因为我想在运行 ssh 服务器的主机上运行动态的本地 PyQt4 脚本,该服务器已连接我的 Open*** 服务器并询问他们的路由首选项(拆分隧道) .

只要您连接的 ssh 服务器具有脚本所需的所有依赖项(在我的情况下为 PyQt4),您就可以通过将数据编码为 base64 并使用 exec() 内置函数轻松封装数据在解码的消息上。如果我没记错的话,我的一句话是:

stdout = client.exec_command('python -c "exec(\\"' + open('hello.py','r').read().encode('base64').strip('\n') + '\\".decode(\\"base64\\"))"' )[1]

它很难阅读,您必须转义转义序列,因为它们被解释了两次(一次由发送者解释,然后由接收者再次解释)。它也可能需要一些调试,我已经将我的服务器打包到 PCS 或者我只是参考我的 Open*** 路由脚本。

这样做与发送文件的区别在于它从不接触服务器上的磁盘并且直接从内存中运行(当然,除非他们记录命令)。您会发现以这种方式封装信息(虽然效率低下)可以帮助您将数据打包到单个文件中。

例如,您可以使用此方法在主脚本中包含来自外部依赖项(即图像)的原始数据。

【讨论】:

【参考方案5】:
ssh user@machine python < script.py - arg1 arg2

因为cat | 通常不需要

【讨论】:

以上是关于在远程服务器上运行本地 python 脚本的主要内容,如果未能解决你的问题,请参考以下文章

在远程服务器上以 root 身份运行本地脚本 [重复]

sh SSH:在远程服务器上运行本地bash脚本

在 VSCode 中本地保存来自远程服务器的数据帧

如何在远程 Spark 集群上运行本地 Python 脚本?

如何在远程节点上使用selenium上传文件[Python] [关闭]

PyCharm 配置远程python解释器和在本地修改服务器代码