Difference between $'$foo' and $"$foo"
-
echo $'$foo'
: the$'[...]'
token around$foo
interprets$foo
literally (as$foo
) and tries to expand ANSI C-like escape sequences in it, which are not present, soecho
yields$foo
; -
echo $"$foo"
: the$"[...]"
token around$foo
expands$foo
to 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 forpwd
is not available, soecho
yieldspwd
; -
echo $`$foo`
: the`[...]`
token around$foo
allows the expansion of$foo
, so$foo
is expanded to its value (pwd
); the expanded value is run in a subshell, whose output (~/scripts
) replaces the whole`[...]`
token, soecho
yields the$
token followed by the~/scripts
token ($~/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~/scripts
and 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
.