TL; DR:對最簡單的命令使用函數方法,並在引用時遇到任何問題時切換到外部腳本。一起避免sh -c
。
我們可以have a look at the git source。它以特定的方式解析引號git
,如果結果沒有shell元字符(包括空格),則作爲文件執行,否則執行execlp("sh", "-c", "result \"[email protected]\"", "result \"[email protected]\"", args...)
的等效操作。
此基礎上,以創建別名最好的辦法無疑是創建一個外部腳本,並使用:
[alias]
myAlias = !/path/to/script
它需要一個外部文件,但在其他方面它的更好:
- 你可以使用任何你想要的解釋器。你甚至可以運行
bash
代碼,因爲你問,而其他形式只允許你運行sh
代碼(差別就像C++ vs C)。
- 除非您想要,否則不會啓動額外的shell。
git
將execve
直接執行您的可執行文件。
- 不需要轉義。這只是一個普通的腳本。
- 沒有驚喜或
git
知識需要。這只是一個腳本。
出你的建議,亞軍是:
[alias]
fAlias = "!f() { ... ; }; f"
這是不太真棒,因爲:
- 你不幸只能
sh
運行,因此不能使用任何bash
功能。
- 一個外殼總是啓動,但至少它只是一個。
- 部分
git
報價需要特定轉義。
- 您需要注意
git
的轉義,但通常無法確切知道它是如何執行命令的,因爲您只會使用該函數的參數。
最後一個是迄今爲止最糟糕的:
[alias]
shAlias = !sh -c \" ... \"
這是可怕的,因爲:
- 只能用
sh
運行。
- 它將無緣無故地啓動額外的shell。
- 您需要均爲
git
轉義並且還有一個額外的轉義級別sh
轉義。
- 你需要知道怎樣逃生代碼
sh
,如何雙重逃生與git
,以及如何git
追加"[email protected]"
你的命令,如果有額外的參數,並通過附加參數$1
,$2
。
爲了證明實用性差,讓我們假設你想建立一個別名這個命令通過ssh
獲得一個遠程服務器上的路徑:
ssh "$1" 'echo "$PATH"'
您可以複製粘貼它逐字到一個文件,添加一個家當,並使用:
[alias]
get-remote-path = !/path/to/my/script
或者你也可以加一點git
逃逸,我們Ë功能的方法:
[alias]
get-remote-path = "!f() { ssh \"$1\" 'echo \"$PATH\"'; }; f"
或者我們可以費力地逃脫,並與sh -c
方法(不,它不會不最後一個字工作)再次逃脫
[alias]
get-remote-path = !sh -c 'ssh \"$1\" '\\''echo \"$PATH\"'\\' cthulhu
顯然,這是更好地使用腳本,或者最糟糕的功能方法,直到你需要更復雜的命令,你可以舒適地引用。
不知道克蘇魯的參考是否是一個笑話...猜測當我找出答案我會知道我是一個真正的shell scripter; P – henry