在远程计算机中通过sshClient()和Paramiko执行本地python脚本

在远程计算机中通过sshClient()和Paramiko执行本地python脚本,python,paramiko,Python,Paramiko,这是我在StackOverflow中的第一篇文章,所以我希望用正确的方法来完成它!:) 我的新工作需要连接到多个服务器,并在所有服务器中执行python脚本。我对服务器不是很熟悉(而且刚刚开始使用paramiko),所以我为任何重大错误道歉 我想在它们上运行的脚本修改了authorized_keys文件,但首先,我只在一台服务器上尝试,还没有使用前面提到的脚本(我不想在第一个任务中出错并阻止服务器!)。 我只是想用一个非常简单的函数getDir()列出远程机器中的目录。到目前为止,我已经能够使用

这是我在StackOverflow中的第一篇文章,所以我希望用正确的方法来完成它!:)

我的新工作需要连接到多个服务器,并在所有服务器中执行python脚本。我对服务器不是很熟悉(而且刚刚开始使用paramiko),所以我为任何重大错误道歉

我想在它们上运行的脚本修改了authorized_keys文件,但首先,我只在一台服务器上尝试,还没有使用前面提到的脚本(我不想在第一个任务中出错并阻止服务器!)。 我只是想用一个非常简单的函数getDir()列出远程机器中的目录。到目前为止,我已经能够使用基础知识通过paramiko连接到服务器(顺便说一下,我正在使用pdb调试脚本):

试试帕拉米科

#!/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())
#!/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

#!/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
def get_dir():
    return ', '.join(os.listdir(os.getcwd()))
调试时,我得到了本地机器的目录列表,而不是远程机器的目录列表。。。有没有办法将python函数作为参数传递给paramiko?我只想让脚本在本地运行,然后像您使用ssh中的bash文件一样远程运行它,方法是:

ssh -i pth/to/key username@domain.com 'bash -s' < script.sh
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
def get_dir():
    return ', '.join(os.listdir(os.getcwd()))
但有了这个,它实际上会尝试以命令的形式运行本地目录列表(这在我使用它的方式上是有意义的)。我必须将列表转换为字符串,因为我遇到一个类型错误,表示它需要字符串或只读字符缓冲区,而不是列表。。。我知道这是一个绝望的尝试通过功能。。。有人知道我是如何做到这一点的吗(通过paramiko传递一个本地函数在远程机器上执行)? 如果您对代码有任何修改或提示,我们非常欢迎(事实上,非常感谢您提供的任何帮助!)


提前多谢!:)

您不能仅仅通过ssh执行python函数。ssh只是一个隧道,代码在一端(客户端),shell在另一端(服务器)。您应该在远程端执行shell命令


如果使用原始ssh代码并不重要,我建议将其作为编写管理工具的库。它包含用于简化ssh处理、文件传输、sudo、并行执行和其他功能的工具。

我认为您可能需要更改传递到
ssh.exec_命令的参数。
以下是一个想法:

而不是做:

def get_dir():
    return ', '.join(os.listdir(os.getcwd()))

i, o, e = ssh.exec_command(getDir())
您可能要尝试:

i, o, e = ssh.exec_command('pwd')
o.printlines()
以及其他需要探索的事情:

  • 编写服务器上的bash脚本或Python。您可以使用Paramiko登录到服务器并使用
    ssh.exec_命令(some_script.sh)
    ssh.exec_命令(some_script.py)
  • Paramiko有一些FTP/SFTP实用程序,因此您可以使用它将脚本放到服务器上,然后执行它

可以使用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())
remotepypath=“/usr/bin/”
#将模块作为文本文件打开
以open(“getDir.py”、“r”)作为f:
mymodule=f.read()
#从操作代码设置
ssh=paramiko.SSHClient()
ssh.load_host_密钥(“pth/to/known_hosts”)
ssh.set_缺少_主机_密钥_策略(paramiko.AutoAddPolicy())
my_key=paramiko.RSAKey.from_private_key_文件(“pth/to/id_rsa”)
connect(server,username=“root”,pkey=my\u key)
#使用here文档将模块输入python解释器

stdin,stdout,stderr=ssh.exec_命令(“{p}”python-检查这个@Bula,非常感谢。我现在切换到Fabric来做!非常感谢@mechmind,我要切换到Fabric。你真的帮了我的忙!我试图对你的答案给出一些分数,但我仍然是一个新手,没有多少声誉分数!很抱歉!非常感谢Stephen!问题是我想避免复制file到所有服务器。我知道我可以将文件scp到所有服务器,但我不希望这样。无论如何,我感谢您抽出时间回答我的问题:)如何将文件传输到服务器?@LukAron文件通过exec_命令()作为文本字符串传输到服务器,从mymodule变量中格式化。我们不会将文件复制到服务器,而是将文件内容提供给远程解释器。该文件永远不会保存到服务器端的磁盘上。