ssh在直接调用命令时挂起,但在交互式运行时干净退出
时间:2020-03-05 18:44:42 来源:igfitidea点击:
我需要在远程计算机上启动服务器,并获取服务器进程进行lsitening的端口号。调用时,服务器将在随机端口上侦听并在stderr上输出端口号。
我想自动化登录到远程计算机,启动该过程以及检索端口号的过程。我编写了一个名为"invokejob.py
"的Python脚本,该脚本驻留在远程计算机上,充当调用该作业然后返回端口号的包装器,如下所示:
import re, subprocess executable = ... # Name of executable regex = ... # Regex to extract the port number from the output p = subprocess.Popen(executable, bufsize=1, # line buffered stderr=subprocess.PIPE ) s = p.stderr.readline() port = re.match(regex).groups()[0] print port
如果我以交互方式登录,则此脚本有效:
$ ssh remotehost.example.com Last login: Thu Aug 28 17:31:18 2008 from localhost $ ./invokejob.py 63409 $ exit logout Connection to remotehost.example.com closed.
(注意:成功注销,它没有挂起)。
但是,如果我尝试从命令行调用它,它将挂起:
$ ssh remotehost.example.com invokejob.py
有谁知道为什么它挂在第二种情况下,我该怎么做才能避免这种情况?
请注意,我需要检索程序的输出,因此我不能只使用ssh" -f"标志或者重定向标准输出。
解决方案
回答
s = p.stderr.readline()
我怀疑这是上面的线。当我们直接通过ssh调用命令时,我们不会获得完整的权限(假设使用Linux),因此就没有可读取的stderr了。
交互式登录时,将为我们设置stdin,stdout和stderr,因此脚本可以工作。
回答
如果我们执行以下操作怎么办:
ssh <远程主机>'<命令>; <我们使用awk或者其他东西的正则表达式>'`
例如
ssh <远程主机>'<程序>; ps aux | awk \'/ root / {print $ 2} \''
这将连接到,执行,然后打印任何用户root或者描述中带有root的任何进程的每个PSID。
我已使用此方法在远程计算机上运行各种命令。问题是用单引号(')将要执行的命令包装起来,并用分号(;)分隔每个命令。
回答
@本·柯林斯
我认为我们将stderr视为问题是正确的。我很确定它阻塞了readline()调用。
最后,我放弃了,并决定使用pexpect中的pxssh模块来自动执行与ssh会话的交互。
@Misha M
不幸的是,分号把戏在这里不起作用:它阻止了我程序的执行。