为什么别名内的变量扩展工作"如预期的那样#34;只有其中一个案例?

时间:2012-01-04 21:31:00

标签: bash variables alias

这个问题的灵感部分来自this one

alias foo='ls -1 $1'
foo /etc

显示/ etc的内容,每行一个项目。

ls -1 /etc | tail

显示/ etc。

中的最后十个项目

但是

alias foo='ls -1 $1 | tail'
foo /etc

显示:tail:错误读取`/ etc':是目录

3 个答案:

答案 0 :(得分:8)

我发现别名中的变量扩展是片状的,不推荐:
http://www.gnu.org/software/bash/manual/bashref.html#Aliases

改为使用函数:function foo() { ls -1 $1; }

答案 1 :(得分:2)

以这种方式完成的别名只会从参数集扩展:

$ alias foo='ls -1 $1 | tail'
$ foo .
# Type Esc-C-e: this expands aliases/globs/environment variables...
# ... And the result of the expansion is:
$ ls -1  | tail .
# $1 has disappeared
$ set bar  # set $1...
$ foo . # again, Esc-C-e
$ ls -1 bar | tail .

答案 2 :(得分:1)

直接回答你的问题:第一种情况符合你的期望是幸运的。

您已经编写了别名,假设$ 1将代表别名的第一个“参数”。实际上,bash中的别名不接受参数,它们只是用你指定的引号中的东西替换别名文本。那么1美元实际上做了什么?

与别名分开,在bash中,$0扩展为键入的第一个东西,即你所在的脚本或shell(命令)。 $1是第一个参数(或第二个类型)。由于您在命令行输入shell,因此shell可能是由运行命令bash且没有参数的终端或窗口管理器启动的。

从命令行尝试:

$ echo $0
bash
$ echo $1
# prints nothing

所以在你的第一个案例中, foo /etc 扩展foo得到 ls -1 $1 /etc 因为$ 1为null,

ls -1 /etc

另外,如果你通过添加| tail将其传播到尾部,它可以正常工作。

在你的第二个案例中 foo /etc 扩展foo得到 ls -1 $1 | tail /etc 因为$ 1为null,

ls -1 | tail /etc

它给出了你得到的错误,因为管道后面的命令出错了:tail无法在目录/etc上运行