单引号内的命令替换别名

单引号内的命令替换别名

bash 中需要使用双引号来进行命令替换:

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

而单引号不进行命令替换:

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

…那么为什么我会看到以下行为,alias这似乎表明命令替换是用单引号发生的?

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

答案1

单引号与双引号版本

让我们使用单引号定义别名:

$ alias d='$(date)'

现在,让我们检索别名的定义:

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

请注意,尚未执行任何命令替换。

让我们做同样的事情,但这次使用双引号:

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

由于使用了双引号,因此在定义别名之前执行命令替换。

单引号版本

让我们尝试执行单引号版本:

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

单引号版本相当于运行:

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

在这两种情况下,命令替换都是在执行命令时执行的。

一个变体

让我们考虑这个使用命令替换并使用单引号定义的别名:

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

每次我们运行此命令时,date都会再次进行评估。使用单引号时,命令替换是在执行别名时执行的,而不是在定义别名时执行的。

答案2

如果在定义别名时使用双引号,则参数扩展发生在别名定义时间。

例如:

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

如果您希望参数扩展发生在您称呼别名,定义别名时使用单引号:

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

当然从来没有任何运行该命令的原因echo "$(date)"。我知道您只是将其用作示例,但由于我“在野外”多次看到此内容,所以我无论如何都会澄清:这意味着什么,运行命令date并捕获输出(剥离任何尾随换行符)。然后将捕获的输出作为参数传递给echo命令,该命令将打印它以及单个尾随换行符。与直接运行相比,没有任何优势date

但是,您在这里也遇到了不同的问题:

设置别名后d='$(date)',当您键入时,您将获得在命令行中d键入的文字结果- 该命令将被执行,捕获输出,尾随换行符将被删除,然后输出将被解析为命令shell(包括分词和文件全局扩展)。$(date)date

由于今天是星期五,因此输出的第一个单词date是“Fri”,因此 shell 尝试将其作为命令运行。

如果你想要的是输入的日期d,只需使用:

alias d=date

或者

alias d='date'

或者

alias d="date"

使用哪种形式并不重要,因为没有特殊字符需要任何形式的引用。

答案3

正在发生吗~/.bashrc?里面有评论的部分~/.bashrc

    95 # Alias definitions.                                              
    96 # You may want to put all your additions into a separate file like
    97 # ~/.bash_aliases, instead of adding them here directly.          
    98 # See /usr/share/doc/bash-doc/examples in the bash-doc package.   

这就是为什么我使用另一个建议的文件作为我的快捷方式:

~/.bash_aliases

关键是转义单引号:

# I use vim but nano or gedit is also fine
vim ~/.bashrc # or vim ~/.bash_aliases
# create your alias:
alias d=''\'date''\'
# or
alias dd="'date'"
# or
alias ddd='"date"'

然后打开一个新的终端会话并d执行您想要的操作。

相关内容