Bash has not added single quotes to the command. The single quotes that you see are added to make displayed command be valid bash syntax. If you see
find -name '"*.log"'
it means that bash was told to execute this command:
find with two arguments
"*.log" (the double quotes being part of the argument). It could have been input exactly like this or in some other equivalent way like
find -name \"*.log\"
find -name "\"*.log\""
find -name '"*.'log""\"
Now let's look at what you wrote:
find `echo "-name \"*.log\""`
The command running in the subshell is
echo "-name \"*.log\""
Its output is
That's where the double quotes in the argument come from. When the output of a command substitution is interpolated into a command line, it is not parsed as shell syntax — so for example
find `echo '; rm -rf ~'`
will not delete all your files but instead pass
; as the first argument to
rm as the second,
-rf as the third and your home directory (assuming it doesn't contain any special characters) as the fourth.
When a variable substitution or a command substitution is outside double quotes, the following transformations happen to the variable's value or the command's output:
- For command substitution only: trailing newlines are stripped.
- The string is broken up into whitespace-delimited pieces. (You can configure the delimiters by setting the
IFS variable.) Note that the result of this transformation is a list of strings.
- Each element of the list is interpreted as a wildcard pattern. If that pattern matches files, then the element is replaced by the list of matching files (this is called globbing). If the pattern doesn't match any file, the element is left alone.
Step 2 breaks the string
-name "*.log" into two pieces:
"*.log". Neither piece matches any file so the result is the two words
What you meant to do is instead run
find with the arguments
*.log. You can do this by turning off globbing:
find `echo -name *.log`
This is not robust: it won't let you pass file names containing whitespace, for example. Generally speaking, you should not attempt to build commands by storing bits of them in a variable or passing them around in commands. The best way to do what you're doing depends on what you're actually trying to do. Here's some general advice: