我正在调试一些必须在我的虚拟机上运行的Python脚本。 我更喜欢本地编辑脚本(在虚拟机外部)。 因此,我发现每次将修改后的脚本scp
到虚拟机中很繁琐。 有人能建议一些有效的方法吗?
特别是,我想知道是否可能在远程PVM上执行Python脚本。 就像这样:
python --remote user@192.168.1.101 hello.py //**FAKED**, served to explain ONLY
我正在调试一些必须在我的虚拟机上运行的Python脚本。 我更喜欢本地编辑脚本(在虚拟机外部)。 因此,我发现每次将修改后的脚本scp
到虚拟机中很繁琐。 有人能建议一些有效的方法吗?
特别是,我想知道是否可能在远程PVM上执行Python脚本。 就像这样:
python --remote user@192.168.1.101 hello.py //**FAKED**, served to explain ONLY
可以使用ssh来实现。Python接受连字符(-)作为执行标准输入的参数。
cat hello.py | ssh user@192.168.1.101 python -
运行 python --help 以获取更多信息。
虽然这个问题不是很新,而且已经有一个答案被选中了,但我想分享另一种好方法。
使用paramiko库——SSH2的纯Python实现——您的Python脚本可以通过SSH连接到远程主机,将自己(!)复制到该主机上,然后在远程主机上执行该副本。远程进程的标准输入、输出和错误输出将在本地运行的脚本上可用。因此,该解决方案与IDE无关。
在我的本地机器上,我使用cmd-line参数“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() 吗? - DiCapriossh user@machine python < script.py - arg1 arg2
因为通常不需要使用cat |
ssh user@192.168.1.101 "python ./hello.py"
你也可以使用文本编辑器或 X11 转发在 ssh 中编辑脚本。我曾经使用Paramiko做过这样的事情,当时我想在运行了我的OpenVPN服务器并连接到它的ssh服务器上运行一个动态的、本地的PyQt4脚本,并询问他们的路由偏好(分割隧道)。
只要你连接的ssh服务器有你的脚本所需的所有依赖项(在我的情况下是PyQt4),你可以通过将数据编码为base64并在解码后使用exec()
内置函数轻松地封装数据。如果我没记错的话,我用一行代码实现了这个:
stdout = client.exec_command('python -c "exec(\\"' + open('hello.py','r').read().encode('base64').strip('\n') + '\\".decode(\\"base64\\"))"' )[1]
这段代码很难阅读,而且你必须转义转义序列,因为它们会被发送者和接收者分别解释两次。它可能还需要一些调试,我已经将我的服务器打包到PCS上了,否则我就可以引用我的OpenVPN路由脚本了。
与发送文件相比,这种方法的不同之处在于它从未触及服务器上的磁盘,而是直接从内存中运行(当然,如果他们记录命令,除外)。你会发现,以这种方式封装信息(虽然效率低下)可以帮助你将数据打包成一个单独的文件。
例如,你可以使用这种方法在主脚本中包含来自外部依赖项(如图像)的原始数据。
cat hello.py | ssh user@192.168.1.101 python - arg1 arg2 arg3
对我有效。"该命令表示将本地的hello.py文件通过ssh传输到IP地址为192.168.1.101的远程主机,并在远程主机上使用python解释器运行该文件,并将arg1,arg2和arg3作为脚本的参数传递。 - Stoopkidcat a_single_file |
,那么你做错了。 - neric