3

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?)

2 Answers 2

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.

0
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.

2
  • 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 ... Jan 17, 2018 at 0:41
  • Right, [ is part of a normal command line with the regular expansion rules. Jan 17, 2018 at 0:49

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .