[英]Run local python script on remote server
I'm debugging some python script that must run on my virtual machine. 我正在调试一些必须在我的虚拟机上运行的python脚本。 And, I prefer to edit the scripts locally(outside of virtual machines).
而且,我更喜欢在本地编辑脚本(在虚拟机之外)。 So I find it's tedious to
scp
modified scripts to virtual machines every time. 所以我发现每次将修改后的脚本
scp
到虚拟机都很繁琐 。 Can anyone suggests some effective way? 有人能建议一些有效的方法吗?
Particularly, I'm wondering if it's possible to execute python scripts on remote PVM. 特别是,我想知道是否可以在远程PVM上执行python脚本。 Something like that:
像这样的东西:
python --remote user@192.168.1.101 hello.py //**FAKED**, served to explain ONLY
It is possible using ssh. 可以使用ssh。 Python accepts hyphen(-) as argument to execute the standard input,
Python接受连字符( - )作为参数来执行标准输入,
cat hello.py | ssh user@192.168.1.101 python -
Run python --help for more info. 运行python --help以获取更多信息。
Although this question isn't quite new and an answer was already chosen, I would like to share another nice approach. 虽然这个问题不是很新,而且已经选择了答案,但我想分享另一个好方法。
Using the paramiko library - a pure python implementation of SSH2 - your python script can connect to a remote host via SSH, copy itself (!) to that host and then execute that copy on the remote host. 使用paramiko库 - SSH2的纯python实现 - 您的python脚本可以通过SSH连接到远程主机,将自身(!)复制到该主机,然后在远程主机上执行该副本。 Stdin, stdout and stderr of the remote process will be available on your local running script.
远程进程的Stdin,stdout和stderr将在您的本地运行脚本上可用。 So this solution is pretty much independent of an IDE.
所以这个解决方案几乎独立于IDE。
On my local machine, I run the script with a cmd-line parameter 'deploy', which triggers the remote execution. 在我的本地计算机上,我使用cmd-line参数'deploy'运行脚本,这会触发远程执行。 Without such a parameter, the actual code intended for the remote host is run.
如果没有这样的参数,则运行用于远程主机的实际代码。
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()
Exception handling is left out to simplify this example. 省略了异常处理以简化此示例。 In projects with multiple script files you will probably have to put all those files (and other dependencies) on the remote host.
在具有多个脚本文件的项目中,您可能必须将所有这些文件(和其他依赖项)放在远程主机上。
ssh user@machine python < script.py - arg1 arg2
Because cat |
因为
cat |
is usually not necessary 通常没有必要
You can do it via ssh. 你可以通过ssh来做。
ssh user@192.168.1.101 "python ./hello.py"
You can also edit the script in ssh using a textual editor or X11 forwarding. 您还可以使用文本编辑器或X11转发在ssh中编辑脚本。
I've had to do this before using Paramiko in a case where I wanted to run a dynamic, local PyQt4 script on a host running an ssh server that has connected my OpenVPN server and ask for their routing preference (split tunneling). 我必须在使用Paramiko之前做到这一点,我想在运行ssh服务器的主机上运行动态的本地PyQt4脚本,该服务器连接了我的OpenVPN服务器并询问它们的路由首选项(拆分隧道)。
So long as the ssh server you are connecting to has all of the required dependencies of your script (PyQt4 in my case), you can easily encapsulate the data by encoding it in base64 and use the exec()
built-in function on the decoded message. 只要您连接的ssh服务器具有脚本的所有必需依赖项(在我的情况下为PyQt4),您可以通过在base64中对其进行编码并使用解码时的
exec()
内置函数轻松封装数据。信息。 If I remember correctly my one-liner for this was: 如果我没记错的话,我的单行代码是:
stdout = client.exec_command('python -c "exec(\\"' + open('hello.py','r').read().encode('base64').strip('\n') + '\\".decode(\\"base64\\"))"' )[1]
It is hard to read and you have to escape the escape sequences because they are interpreted twice (once by the sender and then again by the receiver). 它很难读取,你必须逃避转义序列,因为它们被解释两次(一次由发送者,然后由接收者再次)。 It also may need some debugging, I've packed up my server to PCS or I'd just reference my OpenVPN routing script.
它也可能需要一些调试,我已经将我的服务器打包到PCS或者我只是引用我的OpenVPN路由脚本。
The difference in doing it this way as opposed to sending a file is that it never touches the disk on the server and is run straight from memory (unless of course they log the command). 与发送文件相反,这样做的不同之处在于,它从不接触服务器上的磁盘,而是直接从内存运行(除非他们记录命令)。 You'll find that encapsulating information this way (although inefficient) can help you package data into a single file.
您会发现以这种方式封装信息(尽管效率低下)可以帮助您将数据打包到单个文件中。
For instance, you can use this method to include raw data from external dependencies (ie an image) in your main script. 例如,您可以使用此方法在主脚本中包含来自外部依赖项(即图像)的原始数据。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.