我在编写带参数的git别名时已经湿透了。我见过一些人用
运行shell脚本[alias]
shAlias = !sh -c \" ... \"
和其他人使用
运行功能[alias]
fAlias = "!f() { ... ; }; f"
似乎(一旦我开始加速Bash - 这还不是我现在的地方)我想做的任何事情都可以用任何一种形式来实现。
在什么情况下优先于另一种?
除了可行性,是否有处理差异?内存使用/速度/等?
答案 0 :(得分:5)
TL; DR:对最简单的命令使用函数方法,并在引用出现任何问题时切换到外部脚本。一起避免sh -c
。
我们可以have a look at the git source。它以git
特定方式解析引号,如果结果没有shell元字符(包括空格)则作为文件执行,否则执行等效的execlp("sh", "-c", "result \"$@\"", "result \"$@\"", args...)
。
基于此,创建别名的最佳方法是创建外部脚本并使用:
[alias]
myAlias = !/path/to/script
它需要一个外部文件,但在所有其他方面它更好:
bash
代码,而其他表单只允许您运行sh
代码(区别就像C ++ vs C)。git
会直接execve
您的可执行文件。git
知识。它只是一个剧本。根据你的建议,亚军是:
[alias]
fAlias = "!f() { ... ; }; f"
这不太棒,因为:
sh
投放,因此不会使用任何bash
功能。git
特定的转义。git
的转义,但通常可以在不知道它是如何执行命令的情况下顺利通过,因为您只是使用函数的参数。 最后一个是最糟糕的:
[alias]
shAlias = !sh -c \" ... \"
太可怕了,因为:
sh
。git
转义以及sh
转义的其他级别。sh
的代码,如何使用git
进行双重转义,以及git
如何将"$@"
附加到您的命令中是附加参数,并将其他参数传递为$1
,$2
。 为了演示实际差异,我们假设您想为此命令创建一个别名,以便通过ssh
获取远程服务器上的路径:
ssh "$1" 'echo "$PATH"'
您可以将其逐字复制粘贴到文件中,添加一个shebang,然后使用:
[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
显然,使用脚本更好,或者最糟糕的是功能方法,直到你需要更容易引用的更复杂的命令。
答案 1 :(得分:2)
首选该函数,因为它是由执行别名的shell直接执行的。使用sh -c '...'
会导致另一个进程启动。