2017-10-11 26 views
0

我一直在寫我的腳溼寫的git別名,採取論據。我見過一些人運行shell腳本與我應該在git別名腳本中使用`sh -c 「... 」`或`「!f(){...;}; f」嗎?

[alias] 
    shAlias = !sh -c \" ... \" 

和其他運行功能與

[alias] 
    fAlias = "!f() { ... ; }; f" 

好像(一旦我加快速度擊 - 這是不是在那裏我還沒有)我認爲做的任何事情都可以用任何一種形式實現。

在什麼情況下比另一種更好?

超越可行性,有沒有處理差異?內存使用/速度/等?

回答

2

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。 gitexecve直接執行您的可執行文件。
  • 不需要轉義。這只是一個普通的腳本。
  • 沒有驚喜或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 

顯然,這是更好地使用腳本,或者最糟糕的功能方法,直到你需要更復雜的命令,你可以舒適地引用。

+0

不知道克蘇魯的參考是否是一個笑話...猜測當我找出答案我會知道我是一個真正的shell scripter; P – henry

2

如果適用,則首選該函數,因爲它由任何shell執行別名時直接執行。使用sh -c '...'導致尚未另一個過程開始。

+0

很酷,對於偶爾的用戶來說,這可能是足夠的理由 – henry