我正在编写一个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'', None)
我希望用这个命令命名4个文件。这仍然是不对的。感谢。
答案 0 :(得分:4)
命令
find /home/disk1 -maxdepth 0 -name file1* -o -name file7*
不会产生任何输出。深度0处唯一的对象是/home/disk1
,其名称与两个表达式都不匹配。因此,运行该命令的预期结果为空。你可能想要-maxdepth 1
。但是,如果您不需要递归搜索,则find
过度杀伤;你可以对模式进行全局扩展。
在shell=True
的构造函数中指定subprocess.Popen
时,需要传递包含整个命令的单个字符串,然后将其传递给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)
我会用自己的最后一个。
在指定subprocess.Popen
时,shell=True
对多个元素的列表执行的操作没有详细说明,建议不要使用此用法。 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
会生成从当前工作目录开始的所有文件的递归列表。