我正试图通过将unix"find"命令传递到Python的子进程来获取一个目录中超过60天的最大20个文件。波本。这就是我尝试过的:
# Get largest files older than 60 days
cmd_string = 'find {0} -type f -mtime +60 -size +300M -exec du -sh {{}} ; | sort -rh | head -n20'.format(rmnt)
print(cmd_string)
cmd_args = shlex.split(cmd_string, posix=False)
print(cmd_args[12])
find_out = subprocess.Popen(cmd_args, stdout=subprocess.PIPE).stdout
其中rmnt是目录名(例如"/mnt/active"(。打印语句正确返回命令:
find /mnt/active -type f -mtime +60 -size +300M -exec du -sh {} ; | sort -rh | head -n20
;
但我得到了这个错误:
find: missing argument to `-exec'
我认为这个问题是由于特殊的字符"\"但它正在按预期打印。
更新1.
我发现了类似的问题:find:缺少`-exec';使用子流程时
它处理的是subprocess.call,而不是subprocess。波彭的回答是";没有shell来解释和删除反斜杠";似乎也适用于此。然而,删除了反斜杠后,我仍然会得到一个错误:
find: paths must precede expression: |
此错误表明反斜杠没有传递给查找命令
对于有类似问题的人来说,我的代码中有两个问题。
1.
默认情况下,为子流程。Popen使用shell=False
,因此没有shell来解释和删除反斜杠,如下所述:find:missing argument to `-exec';使用子流程时
2.
要将管道与子流程模块一起使用,必须通过shell=True
,这是一个安全隐患。因此,命令应分为2个或多个命令,如下所述:如何将"子流程"命令与管道一起使用
对我有效的代码是:
# Get largest files older than 60 days
find_cmd = 'find {0} -type f -mtime +60 -size +300M -exec du -sh {{}} ;'.format(rmnt)
find_args = shlex.split(find_cmd)
sort_cmd = 'sort -rh'
sort_args = shlex.split(sort_cmd)
find_process = subprocess.Popen(find_args, stdout=subprocess.PIPE)
sort_process = subprocess.Popen(sort_args, stdin=find_process.stdout,stdout=subprocess.PIPE)
find_process.stdout.close()
sort_out = sort_process.stdout