2

We are recommended that, in bash scripts, we shouldn't parse the output of ls

The webpage linked to above recommends code like:

# Good!
for f in *; do
    [[ -e $f ]] || continue
    ...
done

or to populate an array with filenames

myfiles=( ~/* )

But when I look at these examples, and knowing how bourne shells deal with unquoted strings in general, my sense is that if I used this code on filenames containing spaces the the glob would explode every - space separated - word on the files. e.g. If I have the following directory

$ ls -1  
a file I downloaded from the net.pdf
apple.sh
hello world.txt

and I run this

for file in *
    do printf "%s\n" "$file"
done

I'm expecting unquoted string behaviour. e.g.

a
file
I
downloaded
from
the
net.pdf
apple
hello
world

But what I get is the correct behaviour

a file I downloaded from the net.pdf
apple
hello world

similar for arrays

myfiles=( * )
declare -p myfiles
declare -a myfiles='([0]="a file I downloaded from the net.pdf" [1]="apple" [2]="hello world")'

My question is why is this?
Is it because glob expansion is done after word splitting? (so that these types of file operations produce correct output?)

8

Filename expansion happens after word splitting

https://www.gnu.org/software/bash/manual/html_node/Shell-Expansions.html#Shell-Expansions

The order of expansions is: brace expansion; tilde expansion, parameter and variable expansion, arithmetic expansion, and command substitution (done in a left-to-right fashion); word splitting; and filename expansion.

1

[[ -e $f ]] is a special case. [[ is a reserved word; between [[ and ]] different rules are in effect. One of them is that no word splitting is performed.

  • 1
    ah right. but if [ -e $f ] was used, word splitting would be done, right?. Also I think that in the [[ ]] context, the * character doesn't mean filenames from the current directory, it means "string pattern matching"? e.g. if [[ $interface == wlp* ]]; then ... – the_velour_fog Jan 17 '18 at 0:41
  • Right, [ is part of a normal command line with the regular expansion rules. – Hauke Laging Jan 17 '18 at 0:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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