代码之家  ›  专栏  ›  技术社区  ›  so.very.tired

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

  •  1
  • so.very.tired  · 技术社区  · 8 年前

    我想使用python自动化特定的任务。
    除其他外,此任务包括使用ssh连接到远程服务器,并运行特定程序(称为 prog.out )那个 可以要求也可以不要求用户输入 .
    经过一些研究和权衡我的选择后,我决定使用Python的Paramiko(考虑到以下因素,这可能是错误的……)。

    让我们从简单的可能性开始 程序输出 不询问任何输入,而只是将一些信息打印到控制台:

    int main(int argc, char* argv[]) {
    
            printf("Hey there, fella\n");
            printf("How are you this morning?\n");
            printf("See ya...\n");
    
            return 0;
    }
    

    其编译为: 程序输出 ,并坐在 服务器名称 ,等待执行。
    因此,在这种情况下:

    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 = '')
    

    可以很好地工作,并且可以打印出任何内容 程序输出 生产。
    但如果相反 程序输出 是:

    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管道:

    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 = '')
    

    但我不能提前知道 程序输出 是否需要用户输入。。。
    我正在寻找一种健壮的跑步方式 程序输出 并让用户与它进行必要的交互。 当 程序输出 期望输入?

    编辑

    好的,我做了一些实验,发现从通道读取()的任何尝试都会被阻止,只要 程序输出 尚未退出,但 程序输出 只要未提供输入,就无法退出。。。
    为什么我无法读取已发送的字节 程序输出 即使还没有完成?
    我真的很想模拟用户,好像他或她直接与 程序输出 ...

    1 回复  |  直到 8 年前
        1
  •  3
  •   e4c5    8 年前

    在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的get,可以向 run_a_out ()并从命令行传递它。

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