Go exec不捕获git日志输出

Go exec不捕获git日志输出,git,go,command-line-interface,Git,Go,Command Line Interface,我正在将我们用Ruby编写的Cli工具(使用Thor)翻译成Go 到目前为止,我在传递git命令和捕获所需输出方面没有遇到任何问题 我需要输出时使用的一般代码是: func output(c string, args []string, printOut bool) (string, error) { cmd := exec.Command(c, args...) if verbose { text.Command(c, args) } if

我正在将我们用Ruby编写的Cli工具(使用Thor)翻译成Go

到目前为止,我在传递git命令和捕获所需输出方面没有遇到任何问题

我需要输出时使用的一般代码是:

func output(c string, args []string, printOut bool) (string, error) {
    cmd := exec.Command(c, args...)

    if verbose {
        text.Command(c, args)
    }

    if printOut {
        cmd.Stdout = os.Stdout
        cmd.Stderr = os.Stderr
    }

    output, err := cmd.Output()

    if err != nil {
        reportError()

        return "", err
    }

    reportOk()

    return string(output), nil
}
但是,我对以下命令有一些问题:

git--no pager log--merges--grep='^merge.*(修补程序发布)|(.*from.*(修补程序发布))'--regexp忽略大小写--perl regexp--pretty=格式:%H-n 1

我这样调用输出:

    args := []string{
        "--no-pager", "log", "--merges", "--grep='^merge.*(hotfix|release)|(.*from.*(hotfix|release))'", "--regexp-ignore-case", "--perl-regexp", "--pretty=format:%H", "-n", "1",
    }

    out, err := output(cmd, args, false)
对于某些上下文,此命令用于查找上次发布/修补程序合并的哈希,以便查找从该提交到“现在”要添加到变更日志的所有相关提交

如果我删除
--grep='^merge.*(修补程序| release)|(.*from.*(修补程序| release))--regexp ignore case--perl regexp
,我确实会得到一个提交哈希输出,但我需要regex来确保它是我想要的合并

问题是,
cmd.Output()
在传递完整命令时不返回错误,它只返回一个空字符串

在终端上执行full命令时有效

有人知道我可能做错了什么吗


非常感谢

您正在调用
git grep
,而不让
/bin/sh
/bin/bash
或任何shell1首先在命令上得到它肮脏的小爪子

当使用
--grep
时,我们(我指的是人类在shell中键入命令)编写如下内容:

git log--grep='^merge | whatever'还有什么
在这里使用单引号保护模式不受外壳的影响。单引号确保竖线
|
字符不被视为管道,即,这不是命令:

git日志--grep=^merge |无论什么。。。
这将通过管道将输出从
git log--grep=^merge
传输到
任何东西

我们需要在这里引用,因为shell正在解释我们的命令,并且专门处理一些字符;单引号克服了这一点,并在这个过程中被shell使用。这意味着Git可以看到
--grep=^merge | whatever

但是您没有调用shell。没有什么可保护的。因此,您指示Git查找
“^merge
,即,一个单引号后跟一个帽子/插入符号
^
,后跟一个
m
,后跟一个
e
,依此类推。这在任何提交中都不存在,因此无法获得预期的输出

解决方案很简单:停止对不存在的shell引用内容,这样就不会向Git传递意外的引用。如果出于某种原因确实需要使用shell,请保留引号,但要密切注意其他所有内容,因为不小心调用shell会导致28.41%的CVE(该统计数据与所有统计数据的72.93%一样,都是当场生成的)



1在某些系统上,
/bin/sh
/bin/bash
;在某些情况下,它是
破折号
;在某些方面,它是另一种变体。这有时会造成便携性问题。这里并不重要,因为所有的shell都对它们一视同仁。

传递一个shell来执行完整的命令是有效的:
cmd:=exec.command(“/bin/bash”、“-c”、“git--no pager log--merges--grep='^merge.*(hotfix | release)|(.*from.*(hotfix | release))--regexp ignore case--perl regexp pretty=格式:%H-n 1”)