网上常常有人问这个问题:为何我写的 alias 在 sudo 下就无论用了?spa
$ alias 'll=ls -l'文档 $ sudo ll a-private-dirio sudo: ll: command not foundtable |
为何会这样?由于正常状况下,alias 只有出如今一条简单命令的命令名称的位置(大部分时候是第一个词的位置)才会生效,给命令加上 sudo 前缀,显然命令名称成了 sudo,ll 就不会被展开了。ast
解决办法很神奇,就是把 sudo 自己也设置成一个 alias:原理
$ alias 'sudo=sudo 'command $ sudo ll a-private-dirnext -rw-r--r-- 1 root root ...word ...tab |
注意右边那个 sudo 后面的空格,那才是关键。原理是什么呢?Bash 文档中有写:
If the last character of the alias value is a blank, then the next command word following the alias is also checked for alias expansion.
若是一个 alias 展开后的值的最后一个字符是空白符(空格,制表符,换行符),那么紧跟在它后面的那个词,若是是 alias 的话也会被展开。再举个例子:
$ alias 'echo=echo foo ' $ echo echo echo # 链式展开,三个 echo 全被展开了 foo echo foo echo foo |
这个特性主要就是用在那些接受另一个命令名称做为参数的命令上的,主要就是 sudo,其它的还有 xargs env nohup 等等,你能够一股脑把它们都设置成 alias:
$ alias 'sudo=sudo ' 'xargs=xargs ' 'env=env ' 'nohup=nohup ' |
我很想知道这个特性的来源,是哪一个 Shell 先实现的。因而查了一下:sh 没有 alias 功能;csh 最早有了 alias 功能,但它没有这个特性;ksh88 从 csh 抄了 alias 过来的时候就已经有了这个特性了;Bash 87 年才有的,因此很大多是 Bash 从 ksh 学来的这个特性,也就是说颇有多是 David Korn 发明的这个特性。