In bash :
echo "*" #Globbing is never done
echo "$variable" # Variable expansion is always done
echo "$(command)" # command expansion is always done
echo '*' #Globbing is never done
echo '$variable' # Variable expansion is never done
echo '$(command)' # command expansion is never done
echo * #Globbing always done.
echo $variable; # Variable expansion is always done
echo $(command) # command expansion is always done
will this apply for all commands?
If you are an American, using quotation marks could hardly be simpler: Use double quotation marks at all times unless quoting something within a quotation, when you use single. It's different in the greater Anglosphere, where they generally use singles in books and doubles in newspapers.
General Usage Rules In America, Canada, Australia and New Zealand, the general rule is that double quotes are used to denote direct speech. Single quotes are used to enclose a quote within a quote, a quote within a headline, or a title within a quote.
The main difference between double quotes and single quotes is, double quotes are used to denote a speech or a quotation whereas single quotes are used to indicate quote within a quotation.
Single quotation marks are also known as 'quote marks', 'quotes', 'speech marks' or 'inverted commas'. Use them to: show direct speech and the quoted work of other writers. enclose the title of certain works.
It looks like you are looking for exceptions, and I'd guess you have some in mind. I'm going to make the assumption that set -f
/set -o noglob
are being excluded from this case?
When you use the dd
command, globbing will not occure, even if unquoted.
$ ls *.txt
blah.txt file1.txt file2.txt file.txt logfile.txt
$ dd if=*.txt of=glob.txt
dd: failed to open ‘*.txt’: No such file or directory
Rebuttal and false positives
Here are some examples that are odd, but follow expansion
variable='2010-09-08 12:34:56'
echo "$variable" | xargs date +%s -d
date: extra operand '12:34:56'
The extra operand shows that variable expansion is happening, you are losing the quotes in the pipe.
$ date +%s -d 2010-09-08 12:34:56
date: extra operand ‘12:34:56’
This also happens if you create a script to echo $1
and then expand your quoted variable while passing. It expands, and works as expected. So, the issue is not with xargs, but with your expansion before the pipe which is normal.
bash -c
, except it takes one argument. So, again, this is not an expansion issue, but a command usage issue.cmd='printf "%s\n" "$(date -d "$variable" +%c)"'
bash -c $cmd
works the same as the expanded version
$ bash -c printf "%s\n" "$(date -d "$variable" +%c)"
printf: usage: printf [-v var] format [arguments]
I really enjoyed Hauri's $'...' and $"..." information--however, those are not the samething we are talking about. They are in fact behaving as the bash man page says they should. $'' is as different from '' as (()) is from $(())
I got excited about this one, so...
$ ls
mclark.txt qt sign_in.txt skel.bash
$ zip m*t.zip *t
$ ls *.zip
m*t.zip
However, this isn't right either-- the splat expands, but upon no match zip uses it as a literal. I found a few commands that did this, but if there was a match (I added a my.zip later) it uses the matched expansion (an error was thrown, b/c my.zip was a text file for testing purposes).
There are multiple forces in place. In general you can assume that single quotes is to hide the contents from bash expansion. Double quotes is to group values which might have white space so that bash sees them as one logical unit but also disable globbing. There are many caveats though...
Enclosing characters in double quotes preserves the literal value of all characters within the quotes, with the exception of $, ', \, and, when history expansion is enabled, !. The characters $ and ' retain their special meaning within double quotes. The backslash retains its special meaning only when followed by one of the following characters: $, ', ", \, or . A double quote may be quoted within double quotes by preceding it with a backslash. If enabled, history expansion will be performed unless an ! appearing in double quotes is escaped using a backslash. The backslash pre-ceding the ! is not removed.
See section QUOTING from man bash
This example below, will either confuse you further or make it clearer.
$ echo "*test*"
*test*
$ echo '*test*'
*test*
$ msg=$(echo '*test*')
$ echo '$msg'
$msg
$ echo "$msg"
*test*
$ echo $msg
speedtest test1 test2 test3 test4 test5 testdir
note that if there were no matches it would print *test*
not empty line as commented by Hastur.
some other interesting tidbits
note that this doesn't work
$ echo 'single quotes don\'t escape'
but this works
$ echo "\"double quotes\" escape"
but you can use one in other without escaping
$ echo '"' "'"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With