Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Bash find or xargs evaluates variables and subshells only once

I noticed that find ... -exec ... {} \; or xargs -i ... {} seems to evaluate variables or subshells (like $RANDOM or $(uuidgen)) only once, even the command was executed mutiple times.

For example:

$ find . -type f -name \*.txt -exec echo "$RANDOM {}" \;
28855 ./foo/bar.txt
28855 ./foo/bar1.txt
28855 ./foo/bar2.txt
28855 ./foo/bar3.txt
28855 ./foo/bar4.txt

$ grep -lr SOME_TEXT --include=\*.txt | xargs -i echo "$RANDOM {}"
6153 ./foo/bar.txt
6153 ./foo/bar1.txt
6153 ./foo/bar2.txt
6153 ./foo/bar3.txt
6153 ./foo/bar4.txt

Is there a way to get a result like below?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

1543 ./foo/bar.txt
543 ./foo/bar1.txt
57224 ./foo/bar2.txt
3525 ./foo/bar3.txt
18952 ./foo/bar4.txt

>Solution :

Yes. The variable expansion is performed after the line has been accepted, but before it has been executed. This means that the command that ends up being executed is

'/usr/bin/find' '.' '-type' 'f' '-name' '*.txt' '-exec' 'echo' '28855 {}' ';'

Two basic ways around this:

  • Use another bash that will delay the execution:

    find . -type f -name \*.txt -exec bash -c 'echo "$RANDOM {}"' \;
    
  • Use a loop:

    for file in $(find . -type f -name \*.txt -print)
    do
      echo "$RANDOM $file"
    done
    
  • If your files have spaces, you have to do something different to preserve them:

    mapfile -d '' files < <(find . -type f -name \*.txt -print0)
    for file in "${files[@]}"
    do
      echo "$RANDOM $file"
    done
    
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading