there are two files in current dir
[root@workspace tmp]# ll
total 8
-rw-------. 1 root root 6 Mar 31 13:18 *
-rw-------. 1 root root 6 Mar 31 13:18 ?
[root@workspace tmp]# for f in "`find . -type f`";do echo "$f";done
./*
./?
[root@workspace tmp]# for f in "`find . -type f`";do echo $f;done
./* ./? ./* ./?
I am confused about the output of the two echo ...
the differenct is: the double quote around the $f
why the outputs are so, anyone can explain this?
thanx any help in advance.
The shell expands the commands before executing them. There are 7 consecutive expansions: brace expansion, tilde expansion, parameter and variable expansion, command substitution, arithmetic expansion, word splitting, and pathname expansion (see this section of the bash manual).
In your case brace expansion, tilde expansion and arithmetic expansion have no effect because you do not use these features.
Before the
forloop is executed command substitution replaces thefindcommand with./? ./*. Because it is enclosed in double quotes the word splitting does not split./? ./*and filename expansion is skipped. Theforcommand is thus not further transformed before execution. The loop iterates only once with value./? ./*of variablef.In
echo "$f"$fis expanded (parameter expansion) and replaced with the value of variablef. Again, because of the double quotes, word splitting and filename expansion are skipped, the result is printed without further modifications, and you see./? ./*.In
echo $f,$fis also expanded and replaced with the value offbut the expansion continues with word splitting and pathname expansion. Word splitting separates the two words./?and./*such that they are treated separately in the next steps. Pathname expansion replaces./?with the list of all single-character file names in current directory (in your case./?and./*) and./*is replaced with the list of all file names in current directory (in your case./?and./*). So, finally what is echoed is./? ./* ./? ./*.