Shell – Passing arguments from one command into the next

argumentslinuxshell

I'm trying to write a script to unify two separate commands I run by hand into a single bash script I can then cron.

The first command is a simple find on files with a certain name and size

find /some/path -type f -name file.pl -size +10M

This will produce several matching files and their full path. I then copy these paths by hand into a for loop as arguments to the next script.

for path in /some/path/1/file.pl /some/path/2/file.pl /some/path/3/file.pl ; do perl /my/script.pl $path ; done

Seems like it should be easy to get this into a single shell script but finding it a struggle.

Best Answer

That's what the -exec predicate is for:

find /some/path -type f -name file.pl -size +10M -exec perl /my/script.pl {} \;

If you do want to have your shell run the commands based on the output of find, then that will have to be bash/zsh specific if you want to be reliable as in:

  • zsh:

    IFS=$'\0'
    for f ($(find /some/path -type f -name file.pl -size +10M -print0)) {
      /my/script.pl $f
    }
    

    though in zsh, you can simply do:

    for f (./**/file.pl(.LM+10)) /my/script.pl $f
    
  • bash/zsh

    while IFS= read -rd '' -u3 file; do
      /my/script.pl "$file"
    done 3< <(find /some/path -type f -name file.pl -size +10M -print0)
    

Whatever you do, in bash or other POSIX shells, avoid:

for file in $(find...)

Or at least make it less bad by fixing the field separator to newline and disable globbing:

IFS='
'; set -f; for file in $(find...)

(which will still fail for file paths that contain newline characters).

Related Question