带引号的子进程命令不起作用

时间:2017-09-10 01:43:51

标签: python string subprocess

我的子进程命令无法使用引号。

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

有什么问题?

2 个答案:

答案 0 :(得分:1)

您需要在Popen实例上运行communic()。它应该看起来像

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)

这不是最佳方法,您可以在this topic找到更多方法。

答案 1 :(得分:1)

我认为问题根本不是引用。

该命令正在执行tail -f,根据定义,它永远不会终止(它会保留拖尾文件)。当你在shell上调用它时,你会立即看到一些输出(可能,取决于grep是否匹配)。但它可能不会返回提示符,因为尾部仍在运行。

如果您真的想要关注该文件,那么您不应该使用communication(),因为它需要一个终止进程。你必须继续读取stdout(和stderr,为了安全!),直到进程终止。

但我怀疑你需要做的就是删除尾部的-f:

x = seq(-1, 1, l = 1e4)
y = dcauchy(x, 0, sqrt(2)/2)
y[c(x == -1, x == 0, x == 1)] ## This subsetting format doesn't work 

如果删除-f,那么communication()就是正确的使用调用。

或者,您可以使用check_output帮助程序:

tail = subprocess.Popen('tail -n 1 /mnt/syslog/**/*.log | egrep -v \'^$|mnt\'',\
        shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)