简体   繁体   中英

Strange behavior with bash for loop

I have this small script:

#!/bin/bash

output=`find "/home/tran/myfolder" -maxdepth 1 -mindepth 1 -type d`
for folder in "$output"
do
    echo "This is $folder"
    echo "$folder exist"
done

The result is:

This is /home/tran/myfolder/folder1
/home/tran/myfolder/folder2
/home/tran/myfolder/folder3
/home/tran/myfolder/folder1
/home/tran/myfolder/folder2
/home/tran/myfolder/folder3 exist

Can you explain me why the loop behaves like that ? Any reply is appreciated.

Bash FAQ 001 covers the correct way to iterate over the output of a command line by line. However, unless you know something about the results before hand, there is no guarantee that the output of find produces one file per line, because a newline is a valid filename character.

In your case, you don't need find ; iterating over a filename pattern will produce the result your want:

for folder in /home/tran/myfolder/*/; do
    echo "$folder"
done

Never iterate over filenames with a for in loop. That's because filenames on UNIX may contain spaces and if they do, the for in loop will break: Let's say you have a file called head tail.txt . In that case the loop would iterate over head and tail.txt .

You could use find directly to achieve the desired result:

find PATH -maxdepth 1 -mindepth 1 -type d -printf "This is %f\nfolder exists\n"

You could also use a glob expression like chepner explained . Iterating over the results of a glob expression is safe because the results of the glob won't be subject to word splitting.

这是因为$output周围有" (双引号),它被当作一个字符串处理

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM