I am having difficulties figuring out some the nuances between single and double quotes within a variable context
I define:
foo=pwdthen run these:
echo $'$foo'Which echos $foo (meaning the first $ in my echo command is dropped)
echo $"$foo"This echos pwd (which means the bash expands $foo, my variable, to its value)
echo $`$foo`Finally this echos $~/scripts (I expected it to print ~/scripts and not $~/scripts)
can somebody help me figure out these differences?
2 Answers
echo $'$foo': the$'[...]'token around$foointerprets$fooliterally (as$foo) and tries to expand ANSI C-like escape sequences in it, which are not present, soechoyields$foo;echo $"$foo": the$"[...]"token around$fooexpands$footo its value (pwd) and tries to translate it if the current locale is not POSIX / C; this is not happening, because either the current locale is POSIX / C or a translation forpwdis not available, soechoyieldspwd;echo $`$foo`: the`[...]`token around$fooallows the expansion of$foo, so$foois expanded to its value (pwd); the expanded value is run in a subshell, whose output (~/scripts) replaces the whole`[...]`token, soechoyields the$token followed by the~/scriptstoken ($~/scripts).
Ultimately, the last one prints $~/scripts because $`foo` is a combination of a literal $ followed by a command substitution; so the leading $ is interpreted as a literal $ and the trailing `$foo` as a command substitution.
First case:
echo $'$foo'Which echos
$foo(meaning the first$in my echo command is dropped)
The first $ is run as a command. Echo doesn't require spaces between arguments, it just takes them.
So echo $'$foo' expands to run the command $ (which isn't a command so it ignores it) and then echo '$foo'. Anything in '' is taken at face value - it doesn't expand it or anything. You can put what you want in '' and nothing happens.
If you replace the $ with $$ it echos the process ID.
Second:
echo $"$foo"This echos
pwd(which means the bash expands$foo, my variable, to its value)
That's because "" doesn't prevent it expanding. "" is normally used to ensure there is a value to compare to.
If you have a variable that could be empty (e.g. it is from a grep result) then you want to compare to another value / variable, you have to put the first variable in "". This ensures that there is always a comparison to check, rather than just an empty section of code (as bash sees) which gives an error.
Finally, number 3. This is interesting.
echo $`$foo`This echos
$~/scripts(I expected it to print~/scriptsand not$~/scripts)
That's because (in this case) echo is printing the $ character first. Putting something in backticks causes the value of the variable to be run as a command (the better way to do it in more recent versions of bash is $(command))
So first it echos $ then it expands `$foo` to `pwd` which is run and returns ~/Scripts. But we had the $ print earlier - so the whole output is $~/Scripts.