thisfred
thisfred

Reputation: 211

Why does this script not find directories with names ending in spaces

I have the following script to recursively clean up directories when they no longer contain (any directories with) any .mp3 or .ogg files:

  set -u
  find -L $1 -depth -type d | while read dir
  do
    songList=`find -L "$dir" -type f \( -iname '*.ogg' -o -iname '*.mp3' \)` && {
      if [[ -z "$songList" ]]
      then
        echo removing "$dir"
        rm -rf "$dir"
      fi
    }
  done

This works great, except that it fails in the case of directories that have a space as the last character of their name, in which case the second find fails, with the following feedback, if the script is invoked with . as its only argument, and a directory with the path './FOO/BAR BAZ ' (note the space at the end) exists:

find: `./FOO/BAR BAZ': No such file or directory

(Note the space that is now missing at the end, though other spaces are left intact.)

I'm pretty sure it's a quoting thing, but every other way of quoting I've tried makes the behavior worse (i.e. more directories failing).

Upvotes: 0

Views: 65

Answers (1)

devnull
devnull

Reputation: 123448

read is splitting the input when it encounters spaces. Quoting help read:

Read a line from the standard input and split it into fields.

Reads a single line from the standard input, or from file descriptor FD
if the -u option is supplied.  The line is split into fields as with word
splitting, and the first word is assigned to the first NAME, the second
word to the second NAME, and so on, with any leftover words assigned to
the last NAME.  Only the characters found in $IFS are recognized as word
delimiters.

You could set IFS and avoid the word splitting. Say:

find -L "$1" -depth -type d | while IFS='' read dir

Upvotes: 5

Related Questions