引号不起作用的子过程命令



我的子过程命令不使用引号。

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)

这不是最好的方法,您可以在此主题中找到更多。

最新更新