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, so echo 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 for pwd is not available, so echo yields pwd;
  • 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, so echo 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.