2017-10-11 27 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