Bash
Bash shadow a command - 與命令同名的函式
我有一個功能
.bashrc
可以自動 sudo 打開我無法寫入的文件:vim() { if [ -w "$1" ]; then \vim "$1" else sudo env HOME="$HOME" \vim -u ~/.vimrc "$1" fi }
當文件需要 sudo 時,它可以正常工作。如果沒有,它會遞歸呼叫此函式並使用 1 個 CPU 的 100%,直到我 CC。
從這個答案我看到有幾個選項,我都試過了。一個實際上有效:
'vim' "$1" #fails \vim "$1" #fails command vim "$1" #Works!
為什麼其他選項不能像我期望的那樣工作?
(我知道這是重複的,但是很難用目前的問題標題在 SO/SE 上找到我的答案,所以我想發布一個問題,標題是我和其他人可以通過Google搜尋找到的)
別名前面的任何字元都會阻止別名觸發:
alias ls='ls -la' ls foo.txt #will run ls -la foo.txt \ls foo.txt #will run ls foo.txt 'ls' foo.txt #will run ls foo.txt 'ls foo.txt' #will run ls foo.txt
但是,這不會停止函式,
command
如果您創建具有相同名稱的函式,則需要引用底層內置函式。ls () { echo "not an alias" } alias ls='echo "an alias"' ls foo.txt #will echo "an alias" \ls foo.txt #will echo "not an alias" 'ls' foo.txt #will echo "not an alias" command ls foo.txt #will actually run `ls`
解釋
問題是前兩個選項只能處理別名。它們不是特殊的重定向運算符,可以感知您是否有同名的函式或命令。他們所做的只是在別名前面放一些東西,因為別名只有在它們是管道或命令的第一部分時才會擴展
alias v='sudo vim' v x.txt #automatically expands "v" to "sudo vim" and then does the rest of the command # v x.txt ==> sudo vim x.txt
Bash 只是嘗試使用它知道的別名列表來擴展命令的第一個單詞(您可以使用 得到
alias
)。別名不帶參數,並且只能是命令中的第一個單詞(空格分隔;vim x.txt
不會擴展為sudo vimim x.txt
使用上面的別名)以正確擴展。但是,擴展永遠不會發生在單引號中:
echo '$USER'
將列印出文字$USER
而不是變數所代表的內容。此外,bash 擴展\x
為x
(大部分)。這些不是專門用於轉義別名的額外添加方式,它們只是 bash 擴展編寫方式的一部分。因此,您可以使用這些方法讓別名隱藏命令並且仍然可以訪問實際命令。