6

Double quotes are required in bash for command substitution:

$ echo "$(date)"
Fri Oct 28 19:16:40 EDT 2016

Whereas single quotes do not do command substitution:

$ echo '$(date)'
$(date)

… why then do I see the following behavior with alias that seems to suggest that command substitution happened with single quotes?

alias d='$(date)'
$ d
No command 'Fri' found, did you mean:
   ....
4

Single-quote vs double-quote versions

Let's define the alias using single-quotes:

$ alias d='$(date)'

Now, let's retrieve the definition of the alias:

$ alias d
alias d='$(date)'

Observe that no command substitution was yet performed.

Let's do the same, but this time with double-quotes:

$ alias d="$(date)"
$ alias d
alias d='Fri Oct 28 17:01:12 PDT 2016'

Because double-quotes are used, command substitution was performed before the alias was defined.

Single-quote version

Let's try executing the single-quote version:

$ alias d='$(date)'
$ d
bash: Fri: command not found

The single-quote version is equivalent to running:

$ $(date)
bash: Fri: command not found

In both cases, the command substitution is performed when the command is executed.

A variation

Let's consider this alias which uses command substitution and is defined using single-quotes:

$ alias e='echo $(date)'
$ e
Fri Oct 28 17:05:29 PDT 2016
$ e
Fri Oct 28 17:05:35 PDT 2016

Every time that we run this command, date is evaluated again. With single-quotes, the command substitution is performed when the alias is executed, not when it is defined.

5

If you use double quotes when defining an alias, the parameter expansion occurs at the alias definition time.

For example:

$ pwd
/tmp
$ echo $PWD
/tmp
$ alias p="echo $PWD"
$ p
/tmp
$ cd /
$ pwd
/
$ p
/tmp
$ alias p
alias p='echo /tmp'
$ 

If you want the parameter expansion to occur at the time you call the alias, use single quotes when defining the alias:

$ alias p='echo $PWD'
$ p
/tmp
$ cd /
$ p
/
$ 

Of course there is never any reason to run the command echo "$(date)". I know you used this just as an example, but since I have seen this so many times "in the wild" I'll clarify anyway: What this means is, run the date command and capture the output (stripping off any trailing newlines). Then pass that captured output as an argument to the echo command, which will print it, along with a single trailing newline. There is no advantage at all over just running date directly.

However, you are having a different problem here as well:

When you set the alias d='$(date)', when you type d you will get the literal result of typing $(date) at the command line—the date command will be executed, the output captured, the trailing newline will be stripped, and then the output will be parsed as a command by the shell (including word splitting and file glob expansion).

Since it's Friday, the first word output by date is "Fri", so the shell tries to run this as a command.

If what you want is to see the date when you type d, just use:

alias d=date

or

alias d='date'

or

alias d="date"

It doesn't matter which form you use, as there are no special characters requiring any form of quoting.

  • This was an example to motivate the question only, specifically to show that alias treated the command substitution differently than echo, not meant to be real code. I upvoted but I suggest that you drop the part of your answer explaining why it's not a good idea to run echo "$(date)" – Marcus Junius Brutus Oct 29 '16 at 0:45
  • @MarcusJuniusBrutus, fair enough. :) I've seen that exact style of code so many times (in actual production scripts!) that I'm leaving the explanation in, but I toned it down a bit. – Wildcard Oct 29 '16 at 0:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.