为什么别名foo1 ="echo $ 1"和别名foo2 ="echo' $ 1'"表现得像他们一样?

Gra*_*ale 3 bash whitespace alias echo

在我的.bashrc文件中,我将以下两行:

alias foo1="echo $1"
alias foo2="echo '$1'"
Run Code Online (Sandbox Code Playgroud)

然后,在终端中,我得到以下输出:

$ foo1 hello world
hello world
$ foo2 hello world
 hello world
Run Code Online (Sandbox Code Playgroud)

为什么产生额外的空间foo2

如果我在终端中执行以下操作,则输出如下所示:

$ echo hello world
hello world
$ echo 'hello world'
hello world
Run Code Online (Sandbox Code Playgroud)

这让我认为foo1并且foo2应该做同样的事情.为什么它们实际上并没有输出完全相同的东西,为什么它们仅仅因为一个空格字符而不同?

(另外,为什么它们中的任何一个输出world?我希望只输出第一个参数.)

Cha*_*ffy 8

如果在典型的交互式shell中运行:

$ set --             # this clears the argument list; it's empty by default, but make sure.
$ alias foo1="echo $1"
$ alias foo2="echo '$1'"
$ alias -p 
Run Code Online (Sandbox Code Playgroud)

输出alias -p如下:

$ alias -p
alias foo1='echo '
alias foo2='echo '\'''\'''
Run Code Online (Sandbox Code Playgroud)

值得注意的是,$1s根本不存在 - 因为你在双引号字符串中定义了别名,它们被替换$1为当前shell的上下文中存在的值的当前值,对于交互式shell来说,这将是在启动时是空的.


因此,当你运行:

foo2 hello world
Run Code Online (Sandbox Code Playgroud)

... shell调用的是:

echo '' hello world
Run Code Online (Sandbox Code Playgroud)

因为echo在它的参数之间放置空格,所以打印出来:

 hello world
Run Code Online (Sandbox Code Playgroud)

然而,如果您运行:

foo1 hello world
Run Code Online (Sandbox Code Playgroud)

... shell调用的是:

echo hello world
Run Code Online (Sandbox Code Playgroud)

...因为你可以在foo1发出的别名中看到,alias -p没有没有引用$1左边的记录; 在定义时,它被替换为当前值 - 空字符串.