我想使用python自动执行特定任务。 除其他事项外,此任务包括使用ssh连接到远程服务器,以及运行 可能会或可能不会要求用户输入* 的特定程序(称为它prog.out)。 经过一些研究并权衡了我的选择之后,我决定使用Python的Paramiko(考虑到以下因素,结果可能是错误的)。 *
prog.out
让我们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()是prog.out通过写入其stdin管道来提供输入:
sout.readlines()
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没有退出就从通道进行read()的任何尝试都会被阻止,但是prog.out只要没有提供输入,就无法退出… 如何来了,prog.out即使还没有完成,我也无法读取已经发送的字节? 我真的很想模拟用户,就像他或她直接与prog.out…进行交互一样。
在Paramiko之上构建了一个库,它也许更适合您的需求。
我说的是python fabric(与我无关)
Fabric是一个Python(2.5-2.7)库和命令行工具,用于简化SSH在应用程序部署或系统管理任务中的使用。 它提供了用于执行本地或远程Shell命令(通常或通过sudo)和上载/下载文件的基本操作套件,以及诸如提示正在运行的用户进行输入或中止执行等辅助功能。
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()添加参数,然后从命令行传递它。
run_a_out
简而言之,Fabric为paramiko提供了更高级别的API,其中大部分复杂性都被隐藏了。