当前位置: 首页 > 面试题库 >

exec git命令拒绝重定向到Go中的文件

萧鸿轩
2023-03-14
问题内容

我正在尝试从go调用git日志,并将输出重定向到给定的文件。

cmdArgs = []string{"log", "--numstat", "--reverse", fmt.Sprintf("%s..HEAD", "89c98f5ec48c8ac383ea9e27d792c3dc77fa6240"), `--pretty="format:=%P %H %an %ae %ad %at %s %b"`}

cmdArgs = append(cmdArgs, ">> "+workingDir+"/logs/"+repoName+".log && cat "+workingDir+"/logs/"+repoName+".log")

cmd := exec.Command("git", cmdArgs...)
cmd.Dir = workingDir + repoName

var out bytes.Buffer
var stderr bytes.Buffer
cmd.Stdout = &out
cmd.Stderr = &stderr
err := cmd.Run()
if err != nil {
    fmt.Println("git", strings.Join(cmdArgs, " "), "in", workingDir+repoName)
    fmt.Println(fmt.Sprint(err) + ": " + stderr.String())
    panic(err)
}

失败于

git log --numstat --reverse --pretty="format:=%P %H %an %ae %ad %at %s %b" 89c98f5ec48c8ac383ea9e27d792c3dc77fa6240..HEAD  > /someplace/xx-tmp.log && cat /someplace/xx-tmp.log in /someplace
exit status 128: fatal: ambiguous argument ' > /someplace/xx-tmp.log && cat /someplace/xx-tmp.log: unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'

直接在bash中执行命令没有问题。


问题答案:

Go的cmd.Run()行为类似于C fork()exec()启动新程序的过程。这 并不是
隐式调用Shell,从安全性的角度来看,这是一件非常好的事情。不必要的外壳程序调用通常会导致命令注入漏洞。

如果您 想要 外壳程序可以添加的功能(此处为重定向和复合命令语法),但又想避免安全风险,请从代码中将数据带外传递:

cmdArgs = []string{
  "-c",                      // tells interpreter that script is next argument
  `outfile=$1; shift; "$@" >"$outfile" && cat "$outfile"`, // script to execute
  "_",                                                     // this is $0
  workingDir+"/logs/"+repoName+".log",                     // $1, becomes outfile
  "git", "log", "--numstat", "--reverse",                  // remaining args are in "$@"
  fmt.Sprintf("%s..HEAD", "89c98f5ec48c8ac383ea9e27d792c3dc77fa6240"),
  "--pretty=format:=%P %H %an %ae %ad %at %s %b"
}

cmd := exec.Command("sh", cmdArgs...)

上面的内容等效于以下shell脚本:

#!/bin/sh
#      ^^- not /bin/bash; this only guarantees support for POSIX syntax

outfile=$1                 # assign first positional argument to variable "$outfile"
shift                      # rename $2 to $1, $3 to $2, etc
if "$@" >"$outfile"; then  # run remaining arguments as a single command, stdout to outfile
  cat "$outfile"           # if that succeeded, then cat our "$outfile" to stdout
fi

请注意,我从内部删除了文字引号--pretty=。这是因为当你在shell中运行命令,这些报价作为语法处理 的外壳
-不要在格式字符串中的空间分割的指令。这里,没有外壳程序将该字符串解析为代码。如果我们将引号保留下来,它们将成为格式字符串的文字部分。



 类似资料:
  • 错误: (节点:6772)UnhandledPromiseRejectionWarning:未处理得承诺拒绝.这个错误可能是由于抛出一个没有catch块的异步函数内部,或者是由于拒绝了一个未用.catch()处理的承诺。要在未处理的承诺拒绝时终止节点进程,请使用CLI标志(请参见https://nodejs.org/api/CLI.html#CLI_unhandled_rejections_mod

  • 问题内容: 我试图将命令输出也扔到文件加上控制台。这是因为我要在文件中保留输出记录。我正在执行以下操作,并将其追加到文件,但不在终端上打印输出。 问题答案: 是的,如果您重定向输出,它将不会出现在控制台上。使用。

  • 问题内容: 如何在angularjs中将用户重定向到绝对URL。 例如:我有一个页面,即我当前的网址(http://example.com/submit),一旦用户单击网页中的某个按钮,他就必须重定向到其他网页,例如(’ http: //google.com ‘)。 我尝试使用 但是没有任何效果。 注意: 不应从Web服务器进行重新部署。它是一个REST API。想要在客户端(使用angularj

  • 我想为我的服务器做一些简单的日志记录,它是一个运行在Docker容器中的小Flask应用程序。 这是Dockerfile 正如您在最后一行中看到的,我将stderr和stdout重定向到一个文件。现在我运行这个容器并将外壳放入其中 并观察以下事情: 服务器正在运行,网站正在运行 没有 产生: 但是没有日志...然而,如果我到容器,我可以看到应用程序在控制台中生成输出。 使用Docker时如何正确重

  • 问题内容: 关于在Linux上计时程序的一个小问题:time命令允许测量程序的执行时间: 哪个工作正常。但是,如果我尝试将输出重定向到文件,它将失败。 我知道还有其他一些带有选项-o的时间实现,但是我的问题是关于没有那些选项的命令。 有什么建议么 ? 问题答案: 尝试 将“时间”的STDERR和您的命令组合到time.txt中 或使用 将来自“睡眠”的STDERR放入文件“ sleep.stder

  • 问题内容: 我用了 然后我导入数据库,它显示一个错误: 问题答案: 您仅向“ charmstyle_com”数据库内的“ charmstyle_com”表授予用户权限。您可能想要的是授予“ charmstyle_com”(或至少“ adminnotification_inbox”表)中所有表的权限 或者