I am trying to get the largest 20 files in a directory that are older than 60 days by passing the unix 'find' command to Python's subprocess.Popen. This is what I have tried:
# 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
where rmnt is a directory name (eg. '/mnt/active'). The print statements return the command correctly:
find /mnt/active -type f -mtime +60 -size +300M -exec du -sh {} \; | sort -rh | head -n20
\;
But I am getting this error:
find: missing argument to `-exec'
I thought that the problem was due to the special character "\" but it is being printed as expected.
Update 1.
I found this similar question: find: missing argument to `-exec' when using subprocess
It deals with subprocess.call rather than subprocess.Popen but the answer that "there is no shell to interpret and remove that backslash" seems to apply here also. However, with the backslash removed I still get an error:
find: paths must precede expression: |
This error suggests that the backslash is not being passed to the find command
For anyone that has a similar issue, there are 2 problems in my code.
1.
By default, subprocess.Popen uses
shell=Falseand therefore there is no shell to interpret and remove the backslash as explained here: find: missing argument to `-exec' when using subprocess2.
To use a pipe with the subprocess module, you have to pass
shell=Truewhich is a security hazard. Therefore, the commands should be separated into 2 or more commands as explained here: How to use `subprocess` command with pipesThe code that worked for me is: