我正在编写一个 Python 程序,我需要执行这个相当长的 shell 命令并在我的脚本中接收输出。
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 中键入此查找搜索时,它工作正常。我不知道为什么它不起作用。我在互联网上浪费了最后两个小时。我在这里感到困惑,请帮助我。
编辑:根据评论,我还尝试从参数中省略“shell=True”,这种情况下的响应是:
(b'',无)
我期待使用此命令的 4 个文件的名称。这还是不对。谢谢。
编辑:抱歉,我不是在寻找文件,我是在寻找文件夹。
最佳答案
命令
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
生成从当前工作目录开始的所有文件的递归列表。
关于Python 子进程调用不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25416271/