1

In the book "Beginning Portable Shell Scripting" by Peter Seebach there is an example how to list the contents of all subdirectories of the current directory:

#!/bin/sh
/bin/ls | while read file
do
  if test -d "$file"; then
   ( cd "$file" && ls )
  fi
done

I learned that parsing ls is bad and globbing should be prefered. Do you think the author chooses parsing because there is a portability issue?

I would do:

#!/bin/sh
for file in *
do
 if test -d "$file"; then
  ( cd "$file" && ls )
 fi
done

Thanks,

Somebody

2 Answers 2

3

Both solutions are not robust against weird filenames, nor do they handle directories which begin with ".". I would write this using find, e.g.:

find . -maxdepth 1 -type d -exec ls '{}' ';'

but first I'd question what output is actually required, either for a person to eyeball or a further script to digest.

You'll probably be able to do in a single "find" what is going to cost a lot of process forks with the for/while ... do ... done loop.

1
  • You may want to use + instead of ';'. Also, -maxdepth is specific to GNU find. Commented Feb 11, 2011 at 15:31
2

Globbing is much preferred over parsing ls since it will handle filenames that include spaces and other characters.

For the specific case in your question, you may be able to use nothing more than:

ls */
2
  • Agreed, although I much prefer the solution using find to even get rid of the for loop.
    – raphink
    Commented Feb 11, 2011 at 15:08
  • In this case, the use of ls will handle filenames that include spaces and other characters. The only character that would be a problem is a newline. Commented Feb 11, 2011 at 17:12

Not the answer you're looking for? Browse other questions tagged or ask your own question.