Sudo不读取/.bashrc中的alias怎么破?

今天周末,早上起来上服务器竟然就蒙圈了,用!$调用命令时候没注意,竟然把一个nginx中关于Google PageSpeed的配置文件删除了。真是悲催。。。这当然不是第一次不小心删除文档啦。还好哥有备份的好习惯(其实是我另一台生产环境的centos下有同样的配置文档啦)。不过,定期备份重要文件绝对是明智之选。

即使有备份,如果偶尔不小心删除文件总是给人不好的心情。于是,我决定把rm做一个alias给rm -i。这就是说我们每次删除文档,系统都会给出一个询问提示。这样,我们就不会手快删除了。例如:有时候明明是想打开编译,因为调用历史命令不慎,引用了rm命令。 这个很简单,我们编译一下自己的$HOME/.bashrc就可以了,如下:

vim ~/.bashrc
##########
alias rm="rm -i"
##########
source ~/.bashrc

好了,我们来测试一下!

touch test
rm test
####成功给出提示#######
sudo touch test
sudo rm test
########失败!直接删除了#####

这是神马情况。。。好吧!Google一番,找到解决方案啦。

vim ~/.bashrc
###########
alias sudo="sudo "
###########
source ~/.bashrc
sudo touch test
sudo rm test
######成功给出提示######

这么奇怪的trick?知其然方知其所以然,还是Google一番,有以下一段文字解释(引用自bash手册)。

Aliases allow a string to be substituted for a word when it is used as the first word of a simple command. The shell maintains a list of aliases that may be set and unset with the alias and unalias builtin commands.

The first word of each simple command, if unquoted, is checked to see if it has an alias. If so, that word is replaced by the text of the alias. The characters ‘/’, ‘$’, ‘`’, ‘=’ and any of the shell metacharacters or quoting characters listed above may not appear in an alias name. The replacement text may contain any valid shell input, including shell metacharacters. The first word of the replacement text is tested for aliases, but a word that is identical to an alias being expanded is not expanded a second time. This means that one may alias ls to “ls -F”, for instance, and Bash does not try to recursively expand the replacement text. If the last character of the alias value is a space or tab character, then the next command word following the alias is also checked for alias expansion.

最重要的是第一句和最后一句:
为什么不生效?第一句说明了bash在遇到不包含印好的命令时,会查询是否有别名存在,如果存在则按照别名走,不存在就直接执行了。
为什么生效了?最后一句说明如果alias最后一个字符是空格或者tab符时,那么bash还会继续搜寻后续的命令是否有alias定义。