这是我在StackOverflow中的第一篇文章,所以我希望以正确的方式做到这一点! :)
我有这个任务要做我的新工作,需要连接到多个服务器并在所有服务器中执行python脚本。我对服务器不太熟悉(刚刚开始使用paramiko),所以我为任何重大错误道歉!
我想在它们上运行的脚本修改了authorized_keys文件,但是要开始,我只用一台服务器尝试它,还没有使用上述脚本(我不想犯错误并阻止服务器进入我的第一个任务!)。 我只是试图用一个名为getDir()的非常简单的函数列出远程机器中的目录。到目前为止,我已经能够使用基础知识连接到paramiko服务器(我正在使用pdb来调试脚本):
try_paramiko.py
#!/usr/bin/python
import paramiko
from getDir import get_dir
import pdb
def try_this(server):
pdb.set_trace()
ssh = paramiko.SSHClient()
ssh.load_host_keys("pth/to/known_hosts")
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
my_key = paramiko.RSAKey.from_private_key_file("pth/to/id_rsa")
ssh.connect(server, username = "root", pkey = my_key)
i, o, e = ssh.exec_command(getDir())
这是获取目录列表的功能:
getDir.py
#!/usr/bin/python
import os
import pdb
def get_dir():
pdb.set_trace()
print "Current dir list is:"
for item in os.listdir(os.getcwd()):
print item
调试时我得到了本地机器的目录列表而不是远程机器的目录列表...有没有办法通过paramiko传递python函数作为参数?我想在本地安装脚本并远程运行它,就像使用ssh中的bash文件一样:
ssh -i pth/to/key username@domain.com 'bash -s' < script.sh
所以实际上要避免将python脚本复制到每台机器然后从它们运行它(我猜上面的命令脚本也会被复制到远程机器然后删除,对吧?)有没有办法用paramiko.sshClient()做到这一点?
我还尝试修改代码并使用创建exec_command的通道的标准输出来列出保留脚本的目录,如:
try_paramiko.py
#!/usr/bin/python
import paramiko
from getDir import get_dir
import pdb
def try_this(server):
pdb.set_trace()
ssh = paramiko.SSHClient()
ssh.load_host_keys("pth/to/known_hosts")
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
my_key = paramiko.RSAKey.from_private_key_file("pth/to/id_rsa")
ssh.connect(server, username = "root", pkey = my_key)
i, o, e = ssh.exec_command(getDir())
for line in o.readlines():
print line
for line in e.readlines():
print line
getDir.py
def get_dir():
return ', '.join(os.listdir(os.getcwd()))
但是有了这个,它实际上会尝试将本地目录列表作为命令运行(实际上它们就像我拥有它一样有意义)。我不得不将列表转换为字符串,因为我有一个TypeError说它需要一个字符串或一个只读字符缓冲区,而不是一个列表...我知道这是一个绝望的尝试传递函数...有谁知道我怎么做这样的事情(通过paramiko传递一个本地函数来在远程机器上执行它)? 如果您对代码有任何更正或提示,我们非常欢迎(实际上,非常感谢任何类型的帮助!)。
提前多多感谢! :)
答案 0 :(得分:4)
你不能只通过ssh执行python函数。 ssh只是一个隧道,你的代码在一边(客户端),shell在另一边(服务器)。您应该在远程端执行shell命令。
如果使用原始ssh代码并不重要,我建议将fabric
作为编写管理工具的库。它包含用于轻松进行ssh处理,文件传输,sudo,并行执行等工具。
答案 1 :(得分:0)
可以通过使用here文档将模块馈送到远程服务器的python解释器中来实现。
remotepypath = "/usr/bin/"
# open the module as a text file
with open("getDir.py", "r") as f:
mymodule = f.read()
# setup from OP code
ssh = paramiko.SSHClient()
ssh.load_host_keys("pth/to/known_hosts")
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
my_key = paramiko.RSAKey.from_private_key_file("pth/to/id_rsa")
ssh.connect(server, username = "root", pkey = my_key)
# use here document to feed module into python interpreter
stdin, stdout, stderr = ssh.exec_command("{p}python - <<EOF\n{s}\nEOF".format(p=remotepypath, s=mymodule))
print("stderr: ", stderr.readlines())
print("stdout: ", stdout.readlines())