我的子过程命令不使用引号。
tail = subprocess.Popen('tail -f -n 1 /mnt/syslog/**/*.log | egrep -v '^$|mnt'',
shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
当我执行python file.py时,我会得到一个空行:
# python main.py
^CTraceback (most recent call last):
File "main.py", line 18, in <module>
main()
File "main.py", line 12, in main
line = tail.stdout.readline()
KeyboardInterrupt
您可以看到它在bash中正常工作:
# tail -f -n 1 /mnt/syslog/**/*.log | egrep -v '^$|mnt'
Sep 9 22:44:07 x.x.x.x : %LINK-3-UPDOWN: Interface GigabitEthernet1/0/19, changed state to down
Sep 9 18:32:56 x.x.x.x : %LINK-5-CHANGED: Interface GigabitEthernet1/0/24, changed state to administratively down
怎么了?
我认为问题根本不是引号。
命令正在执行尾巴-f,从定义上讲,它永远不会终止(它一直在尾随文件)。当您在外壳上调用它时,您会立即看到一些输出(也许取决于GREP是否匹配)。但这可能不会返回提示,因为尾巴仍在运行。
如果您真的想关注文件,那么您不应该使用communicate(),因为这会终止过程。您必须继续从Stdout(和STDERR,要安全!)继续阅读,直到过程死亡为止。
,但我怀疑您要做的就是删除尾巴上的-f:
tail = subprocess.Popen('tail -n 1 /mnt/syslog/**/*.log | egrep -v '^$|mnt'',
shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
如果删除-f,则communicate()是正确使用的调用。
或者,您只能使用check_output助手:
subprocess.check_output('tail...', shell=True)
您需要在popen实例上运行communicate()。它应该看起来像
tail = subprocess.Popen('tail -f -n 1 /mnt/syslog/**/*.log | egrep -v '^$|mnt'',
shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
stdout, stderr = tail.communicate()
print(stdout)
如果您需要Unicode字符串而不是字节,请使用DECODE():
print(stdout.decode())
更新:由于-f标志要尾随,您应该实时输出:
tail = subprocess.Popen('tail -f -n 1 /mnt/syslog/**/*.log | egrep -v '^$|mnt'',
shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
for line in tail.stdout:
print(line)
这不是最好的方法,您可以在此主题中找到更多。