0

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

daragh
  • 487
  • 9
  • 18

1 Answers1

0

For anyone that has a similar issue, there are 2 problems in my code.

1.

By default, subprocess.Popen uses shell=False and therefore there is no shell to interpret and remove the backslash as explained here: find: missing argument to `-exec' when using subprocess

2.

To use a pipe with the subprocess module, you have to pass shell=True which is a security hazard. Therefore, the commands should be separated into 2 or more commands as explained here: How to use `subprocess` command with pipes

The code that worked for me is:

# 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
daragh
  • 487
  • 9
  • 18