直接调用命令时 SSH 停滞,但交互式运行时正常退出
我需要在远程机器上启动一个服务器,并获取这个服务器正在监听的端口号。当服务器启动时,它会在一个随机的端口上监听,并把端口号输出到错误信息中。
我想自动化这个过程,包括登录到远程机器、启动服务器进程以及获取端口号。我写了一个叫做"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"选项或者重定向标准输出。
2 个回答
0
如果你这样做会怎么样:
ssh <远程主机> '<你的命令> ;<你的正则表达式,使用awk或其他工具>'
举个例子:
ssh <远程主机> '<你的程序>; ps aux | awk \'/root/ {print $2}\''
这样做会连接到远程主机,执行你的程序,然后打印出所有用户为root的进程ID,或者任何描述中包含root的进程。
我用这种方法在远程机器上运行各种命令。需要注意的是,你想执行的命令要用单引号(')括起来,并且每个命令之间要用分号(;)分开。
3
s = p.stderr.readline()
我怀疑问题出在上面那行。当你通过ssh直接执行一个命令时,你并没有获得完整的终端环境(假设你在使用Linux),因此你无法读取错误信息。
而当你以交互方式登录时,输入、输出和错误输出都会为你设置好,所以你的脚本就能正常工作了。