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
执行您想要的操作。