【问题标题】:How to use a bash function in a git alias?如何在 git 别名中使用 bash 函数?
【发布时间】:2017-09-26 20:50:51
【问题描述】:

我想在 git 别名中使用 bash 函数。所以我将此添加到我的.bashrc

fn() {
    echo "Hello, world!"
}
export -f fn

还有我的.gitconfig:

[alias]
    fn = !fn

但随后git fn 产生错误:

fatal: cannot run fn: No such file or directory
fatal: While expanding alias 'fn': 'fn': No such file or directory

这是在 git 别名定义中使用 bash 函数的正确方法吗?

【问题讨论】:

  • 我假设当 Git 运行 bash 命令时,它会在自己的进程中执行此操作,这很可能会跳过您的 .bashrc。因此,您必须在该别名行中定义 .gitconfig 内的函数。 – 或者,您可以创建一个 git-fn 文件并将其放在 PATH 中,然后 git fn 也应该可以工作(至少 iirc)
  • @poke,export -f的重点是定义在环境中,所以git调用的shell没有 source .bashrc --如果它实际上是 bash。如果是/bin/sh,那么问题在于手头有哪个实现。
  • @CharlesDuffy 有趣,我不知道你可以将函数放入环境中,这很酷。谢谢!

标签: git bash function config alias


【解决方案1】:

那是因为 git 使用了/bin/sh(所以你的.bashrc 没有来源)。

您可以在 this answer 中指定的 git 别名中调用 bash。

问题是 git 命令启动的 bash shell 没有加载您的 .profile(这是负责包含 .bashrc 的那个)。

可能还有其他方法可以做到这一点,但您可以通过以下方式解决:

[alias]
    fn = !bash -c 'source $HOME/.my_functions && fn'

文件.my_functions是这样的:

#!/bin/bash
fn() {
    echo "Hello, world!"
}

如果您希望这些功能可从常规 shell 中使用,您甚至可以将 .my_functions 提供给您的 .bashrc

【讨论】:

  • 如果您是source 文件,则不需要export -f。唯一的价值是,如果您在用户的点文件中运行它,然后尝试从子进程访问先前导出的函数。
  • 这很有效。要将 shell 中的所有参数传递到 fn,您需要在末尾添加一个 ` - `:fn = !bash -c 'source $HOME/.my_functions && fn' -
【解决方案2】:

我不知道为什么,但是如果我只是在.gitconfig 中的函数名称前放一个空格,它就可以正常工作并输出消息:

[alias]
    fn = ! fn

这可能是 git 中的错误,或者我在文档中遗漏了一些内容。

【讨论】:

    【解决方案3】:

    如果您想 100% 确定导出的函数会得到支持,请确保调用的 shell 是 bash,而不是 /bin/sh(如果它是由 ash 或 dash 实现的,则不会支持它们)。

    fn() { echo "hello, world"; }
    export -f fn
    git config --global alias.fn $'!bash -c \'fn "$@"\' _'
    git fn
    

    ...正确发出:

    hello, world
    

    .gitconfig中的相关条目:

    [alias]
        fn = !bash -c 'fn \"$@\"'
    

    【讨论】:

    • 要正确传递参数,您需要提供一个将变为 $0 的虚拟参数:git config --global alias.fn $'!bash -c \'fn "$@"\' x'
    • 对我来说,导出函数不起作用。我必须将它添加到 ~/.bashrc 并使用 $'bash -ic \'...
    • @glennjackman,关于$0 需要一个虚拟参数的好点。也就是说,回复:导出不起作用,你能给我一个复制器吗? (上面的代码在完全按原样复制并粘贴到以前没有定义 fn 的会话中时对我有用)。
    • (也就是说,如果你有两个不同的 bash 版本,我肯定会看到它失败,一个有 shellshock 的供应商或中间上游补丁,另一个有最终的上游补丁;导出的环境表示函数在 shell 的生命周期内不是恒定的)。
    猜你喜欢
    • 2011-09-22
    • 1970-01-01
    • 2020-10-22
    • 2011-11-06
    • 2022-12-23
    • 2016-09-03
    • 2014-03-11
    • 2013-11-19
    • 2013-04-29
    相关资源
    最近更新 更多