Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 带引号的子流程命令无效_Python_String_Subprocess - Fatal编程技术网

Python 带引号的子流程命令无效

Python 带引号的子流程命令无效,python,string,subprocess,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

我的子进程命令不能使用引号

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

怎么了?

您需要在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字符串而不是字节,请使用:

更新: 由于-f标记为tail,因此您应该能够实时获得输出:

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)

这不是最好的方法,你可以从中找到更多。

我认为问题根本不在于引用

命令正在执行tail-f,根据定义,tail-f永远不会终止(它一直跟踪文件)。当您在shell中调用它时,您会立即看到一些输出(可能,取决于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)

你想解决什么问题?您的脚本是否挂起而没有任何输出(这是由
-f
选项引起的,该选项很难与子流程一起使用)?或者是在
变量中得到一个空字符串?问题是没有输出。。我怀疑是这些引语造成的。。如果我删除egret语句并作为tail-f-n1/mnt/syslog/***.log输入,它就可以正常工作。。我在Python中运行时看到输出。我不认为这是引用问题。我认为这是
-f
与带有子流程的管道的组合。例如,删除
-f
,它也会对您有效(至少对我有效)。“工作”指的是给予一些产出。。但是它已经可以在没有白鹭的情况下使用-f了?我得到了预期的输出。一个问题是,为什么您认为您需要
egrep
。让Python进行过滤。有错误消息吗?我没有您的日志,但是简单的ls在python 3.6中非常适合我。没有错误消息。。只是没有输出。。现在,如果我去掉白鹭的部分,它会起作用。。我怀疑是egrep中的引用不起作用。我已经更新了我的答案,并添加了指向另一个有关实时输出的问题的链接。
tail = subprocess.Popen('tail -n 1 /mnt/syslog/**/*.log | egrep -v \'^$|mnt\'',\
        shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
subprocess.check_output('tail...', shell=True)