Bash – What happens when files are added/removed in the middle of a “for f in *” sh loop

bashforshellwildcards

I found one for loop example online. Now I want to use it in my code but I am not sure how does this loop operates

for entry in "$search_dir"/* 
do
  echo "$entry"
done

Now I want to ask that

  1. Does it look in search_dir in each iteration and copies files in search_dir to entry variable one file in each iteration?
  2. Or I take a snapshot of all the contents of search_dir and then store that snapshot to entry variable?
  3. Is there any change in output if some one inserts some file in search_dir while the loop is still working?

Best Answer

When the shell gets to the for-statement, it will expand the value of $search_dir and perform the file name globbing to generate a list of directory entries that will be iterated over. This happens only once, and if the things in $search_dir disappears or if there are new files/directories added to that directory while the loop is executing, these changes will not be picked up.

If the loop operates on the directory entries whose names are in $entry, one might want to test for their existence in the loop, especially if the loop is known to take a long time to run and there are lots of files that are in constant flux for one reason or another:

for entry in "$search_dir"/*; do
    if [ -e "$entry" ]; then
        # operate on "$entry"
    else
        # handle the case that "$entry" went away
    fi
done

As Stéphane rightly points out in comments, this is a superfluous test in most cases.

Related Question