Python subprocess 调用无效
我正在写一个Python程序,需要在我的脚本中执行一个比较长的命令,并获取输出。
test = subprocess.Popen(shlex.split("find /home/disk1 -maxdepth 0 -name folder1* -o -name folder7*"), stdout=subprocess.PIPE, shell=True)
test.communicate()
我尝试了所有可能的代码变种,比如在参数中加上'executable="/bin/bash"',或者使用subprocess.check_output等等。
每次我运行这个命令并通过输入'test.communicate()'来查看输出时,我得到的都是'/home/disk1'目录下的所有文件,而不是我想要的那些文件。可是当我在命令行中输入这个查找命令时,它是正常工作的。我不知道为什么在我的程序里不行。我已经在网上花了两个小时,结果一无所获,真让我困惑,请帮帮我。
补充:根据评论的建议,我也试着把参数中的'shell=True'去掉,这样的返回结果是:
(b'', None)
我本来希望能得到4个文件的名字,但结果还是不对。谢谢。
补充:抱歉,我不是在找文件,我是在找文件夹。
1 个回答
这个命令
find /home/disk1 -maxdepth 0 -name file1* -o -name file7*
不会有任何输出。深度为0的唯一对象是
/home/disk1
,而它的名字和你给的表达式都不匹配。所以运行这个命令的结果是空的。你可能想用-maxdepth 1
。不过,如果你不需要递归搜索的话,使用find
就有点过了;你可以直接用模式进行通配符扩展。当你在
subprocess.Popen
的构造函数中指定shell=True
时,你需要传一个包含整个命令的字符串,这个字符串会被传给一个shell。你可以通过提供一个单独的字符串参数,或者一个只有一个元素的列表(这个元素是字符串)来做到这一点。如果你使用shell=False
,你需要提供一个列表,列表的第一个元素是要运行的程序,后面的元素是参数。因此,下面的任何一种写法都会得到预期的结果:test = subprocess.Popen( "find /home/disk1 -maxdepth 1 -name file1* -o -name file7*" , stdout=subprocess.PIPE, shell=True) test = subprocess.Popen( ["find /home/disk1 -maxdepth 1 -name file1* -o -name file7*"] , stdout=subprocess.PIPE, shell=True) test = subprocess.Popen( shlex.split( "find /home/disk1 -maxdepth 1 -name file1* -o -name file7*") , stdout=subprocess.PIPE) test = subprocess.Popen(["find", "/home/disk1" , "-maxdepth", "1" , "-name", "file1*" , "-o" , "-name", "file7*"] , stdout=subprocess.PIPE)
我个人会选择最后一种。
关于当
shell=True
时,subprocess.Popen
对于包含多个元素的列表的处理并没有很好的文档说明,而且这种用法并不推荐。Posix 实现会把列表中的所有元素添加到 ["sh", "-c"] 中,然后执行它。实际上,这样会执行以下内容:sh -c find /home/disk1 -maxdepth 1 -name "file1*" -o -name "file7*"
在这里,传给
-c
的参数就是find
,/home/disk1
变成了$0
,而$1
到$7
则是剩下的参数。最终的结果是find
被执行时没有命令行参数(在一个名为/home/disk1
的进程中)。没有参数的find
会从当前工作目录开始递归列出所有文件。