使用Python的Paramiko自动执行ssh连接和程序执行

时间:2016-05-07 08:02:43

标签: python ssh paramiko

我想使用python自动执行特定任务 除了其他一些内容之外,此任务还包括将ssh连接到远程服务器,以及运行特定程序(称之为prog.out),可能要求用户输入也可能不要求
经过一些研究并在对我的选项进行加权后,我决定使用Python的Paramiko(考虑到下面的内容可能会出错)。

让我们从prog.out不要求任何输入的简单可能性开始,而只是将一些信息打印到控制台:

int main(int argc, char* argv[]) {

        printf("Hey there, fella\n");
        printf("How are you this morning?\n");
        printf("See ya...\n");

        return 0;
}

编译为:prog.out,并位于 server_name 上,等待执行。
那么在那种情况下:

client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect("server_name")
sin, sout, serr = client.exec_command('./prog.out')

for line in sout.readlines():
    print(line, end = '')

完美无缺,并打印出prog.out产生的任何内容 但如果相反prog.out是:

int main(int argc, char* argv[]) {

        printf("Hey there, fella\n");
        printf("How are you this morning?\n");
        printf("please enter an integer...\n");
        int a;
        scanf("%d", &a);
        printf("you entered %d\n", a);
        printf("see ya...\n");

        return 0;
}

然后上面的python代码会阻塞sout.readlines()(等待eof?)...
sout.readlines()中避免阻塞的方法是通过写入stdin管道为prog.out提供输入:

client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect("server_name")
sin, sout, serr = client.exec_command('./prog.out')

sin.write('55\n')

for line in sout.readlines():
    print(line, end = '')

但我事先无法知道prog.out是否会要求用户输入...
我正在寻找一种运行prog.out的强大方法,并让用户在必要时与其进行交互。 prog.out期望输入时是否有一些指示?

修改

好的,我做了一些实验,发现只要prog.out没有退出,任何从频道读取()的尝试都会阻止,但prog.out无法退出只要它没有提供输入...
为什么即使它还没有完成,我也无法读取prog.out已发送的字节? 我真的很想模仿用户,好像他或她直接与prog.out进行互动......

1 个答案:

答案 0 :(得分:3)

在Paramiko之上建立了一个图书馆,可能更适合您的需求。

我说的是python fabric(其中我没有关联)

  

Fabric是一个Python(2.5-2.7)库和命令行工具   简化SSH在应用程序部署或系统中的使用   管理任务。

     

它提供了执行本地或远程的基本操作套件   shell命令(通常或通过sudo)和上传/下载文件,   以及辅助功能,例如提示正在运行的用户   用于输入或中止执行。

如果我已正确理解您的要求,您的代码可能看起来像这样。

from fabric.api import run

@task
def run_a_out()
    run('echo "some input for a.out" | ./a.out')

您将使用

执行远程程序
    fab --hosts=someserver run_a_out

如果你想动态控制传递给a.out的内容,你可以在run_a_out()中添加一个参数并从命令行传递它。

简而言之,Fabric为paramiko提供了更高级别的API,隐藏了大部分复杂性。