我正在编写一个python脚本来ssh到linux服务器并执行已经存储在linux服务器上的shell脚本。
这是我的代码到目前为止的样子
command = ['ssh into the remote server',
'cd into the directory of the shell script,
'./running the shell script',
]
process = subprocess.Popen(command,
shell=True,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
err, out = process.communicate()
if out:
print "standard output of subprocess is : "
print out
if err:
print "standard error of subprocess is : "
print err
print "returncode of subprocess: "
print process.returncode
第一个问题:我可以通过stderr获取shell脚本的输出,但是我只在整个shell脚本执行完毕后才获得它。因此,如果shell脚本需要10分钟才能完成,我只能在10分钟后看到shell脚本的输出。 我希望我的shell脚本的输出逐行返回给我,就像我在远程服务器中手动执行脚本一样。可以这样做吗?
第二个问题:正如你所看到的,我的命令列表中有三个命令(这只是我所有命令的一小部分),如果我将所有命令放在列表中,我只获取所有命令的输出只有当我的所有命令都完成执行时才通过stdout执行命令。如果我的第一个问题无法完成,是否有办法在每个命令执行完毕后至少获取每个命令的输出,而不是仅在所有命令都已执行完毕后立即接收所有命令。
答案 0 :(得分:0)
我不完全确定,但如果您将其他两个命令作为参数传递给ssh
,也许您可以获得即时输出:
command = 'ssh user@example.com \'cd some/path/on/your/server; ./run-the-script.sh\''
我理解它的方式,Python首先读取并处理所有输入,只有然后返回输出。我对Python不太熟悉,所以我可能错了,但如果我说对了,这应该会有所帮助。
答案 1 :(得分:0)
请勿致电.communicate()
- 等待流程完成。
相反,请继续从.stdout
管道中读取数据。
简单示例:
In [1]: import subprocess
In [2]: p = subprocess.Popen(["find", "/"], stdout=subprocess.PIPE)
In [3]: p.stdout
Out[3]: <open file '<fdopen>', mode 'rb' at 0x7f590446dc00>
In [4]: p.stdout.readline()
Out[4]: '/\n'
In [5]: p.stdout.readline()
Out[5]: '/var\n'
In [6]: p.stdout.readline()
Out[6]: '/var/games\n'
答案 2 :(得分:0)
要立即查看输出,请勿重定向:
from subprocess import Popen, PIPE
p = Popen(['ssh', 'user@hostname'], stdin=PIPE)
p.communicate(b"""cd ..
echo 1st command
echo 2nd command
echo ...
""")
如果您希望两者捕获变量和中的“实时”输出以在终端中显示它,那么解决方案取决于您是否需要处理stdin / stdout / stderr同时发生。
如果输入很小并且您想要组合stdout / stderr,那么您可以立即传递所有命令并逐行读取合并的输出:
from subprocess import Popen, PIPE, STDOUT
p = Popen(['ssh', 'user@hostname'], stdin=PIPE,
stdout=PIPE, stderr=STDOUT, bufsize=1)
p.stdin.write(b"""cd ..
echo 1st command
echo 2nd command
echo ...
""")
p.stdin.close() # no more input
lines = [] # store output here
for line in iter(p.stdout.readline, b''): # newline=b'\n'
lines.append(line) # capture for later
print line, # display now
p.stdout.close()
p.wait()
如果您想分别捕获“live”stdout / stderr,请参阅: