如何正确遍历gitconfig别名上的列表?

时间:2018-07-14 18:16:30

标签: bash git shell

我在.gitconfig上创建了一个别名:

[alias]
    test =  "!f() { \
        for l in "$@"; do \
          echo "$l"; \
        done; \
        }; f"

考虑命令:

git test "foo bar" last

我期望得到:

foo bar
last

但是,我得到了:

foo
bar
last

这与bash上的类似“ for”命令不同。为什么会发生?我应该如何使该命令正常工作?

2 个答案:

答案 0 :(得分:3)

问题是Git去除了别名扩展中的双引号。缩为一行的别名定义为:

"!f() { for l in "$@"; do echo "$l"; done; }; f"

Git去除所有未转义的双引号(当然还有前导!),产生:

f() { for l in $@; do echo $l; done; }; f

您希望外壳看到:

f() { for l in "$@"; do echo "$l"; done; }; f

这意味着您必须将此交给Git:

"!f() { for l in \"$@\"; do echo \"$l\"; done; }; f"

现在每个内部双引号都被转义了,Git会将它们留在那儿供shell查看。

(如果脚本变得复杂,建议不要尝试将其编写为别名。如果您在git-abc上的任何位置都有名为$PATH的可执行脚本,并且您运行git abc,Git将运行您的git-abc脚本。请注意,当Git运行您的脚本时,Git扩展了$PATH使其包含git-core目录,以便您可以使用. git-sh-setup获取各种有用的子例程。)

答案 1 :(得分:0)

发布之前,我发现了一种实现所需功能的方法。我将别名重写为:

[alias]
    test =  "!f() { IFS='\n'; \
        for l in "$@"; do \
          echo "$l"; \
        done; \
        }; f"

IFS重新定义成功了。我只是不确定这是否是最好的方法。我希望在这个问题上有不同的看法。