17

I have a fundamental question about how bash works, and a related practical question.

Fundamental question: suppose I am in a directory that has three subdirectories: a, b, and c.

hen the code

for dir in $(ls)
do 
    echo $dir
done

spits out:

a b c
a b c
a b c

i.e, dir always stores a list of all of the files/directories in my cwd. My question is: why in the world would this be convenient? In my opinion it is far more useful and intuitive to have dir store each element at a time, i.e I would want to have output

a
b
c

Also, as per one of the answers - it is wrong to use for dir in $(ls), but when I use for dir in $(ls -l) I get even more copies of a b c (more than there are directories/files in the cwd). Why is that?

My second question is practical: how do I loop over all the directories (not files!) in my cwd that start with capital W? I started with

for dir in `ls -l W*`

but this fails because a) the reason in question 1 and b) because it doesn't exclude files. Suggestions appreciated.

4

3 に答える 3

44

lsこのような出力を決して解析しないでください( ls(1) の出力を解析すべきではない理由)。

また、構文が間違っています。()というわけではありません$()

そうは言っても、W で始まるディレクトリをループするには、次のfindようにします (シナリオによっては、代わりにコマンドを使用します)。

for path in /my/path/W*; do
    [ -d "${path}" ] || continue # if not a directory, skip
    dirname="$(basename "${path}")"
    do_stuff
done

邪悪な ls ループから得られる出力に関しては、そのように見えるべきではありません。これは予想される出力であり、そもそも ls を使用したくない理由を示しています。

$ find
.
./c
./a
./foo bar
./b

$ type ls
ls is hashed (/bin/ls)

$ for x in $(ls); do echo "${x}"; done
a
b
c
foo
bar
于 2013-04-06T18:40:36.937 に答える