網上常常有人問這個問題:爲何我寫的 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 發明的這個特性。