Go exec不捕获git日志输出
我正在将我们用Ruby编写的Cli工具(使用Thor)翻译成Go 到目前为止,我在传递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
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”)