这个问题的灵感部分来自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':是目录
答案 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
上运行