为啥我的 exec 命令失败但如果命令在终端中传递则可以工作?

Posted

技术标签:

【中文标题】为啥我的 exec 命令失败但如果命令在终端中传递则可以工作?【英文标题】:Why is my exec command failing but works if the command is passed in the terminal?为什么我的 exec 命令失败但如果命令在终端中传递则可以工作? 【发布时间】:2020-07-28 13:30:48 【问题描述】:

出于某种原因,我不明白为什么我的exec 命令出现问题,我相信我遵循了我正确引用的文档和示例。当我在终端中运行此命令时,我没有问题:

gitleaks --repo=https://github.com/user/repo -v --username=foo --password=bar

但是当我尝试将其编码为模块时,我可以在 package.json 中调用它:

const  exec  = require("child_process")
const test = `gitleaks --repo=https://github.com/user/repo -v --username=foo --password=bar`

const execRun = (cmd) => 
  return new Promise((resolve, reject) => 
    exec(cmd, (error, stdout, stderr) => 
      if (error) reject(error)
      resolve(stdout ? stdout : stderr)
    )
  )


(async () => 
try 
  const testing = await execRun(test)
  console.log(testing)
 catch (e) 
  console.log(e)

)()

但我继续收到错误:

 Error: Command failed: gitleaks --repo=https://github.com/user/repo -v --username=foo --password=bar

    at ChildProcess.exithandler (child_process.js:294:12)
    at ChildProcess.emit (events.js:198:13)
    at maybeClose (internal/child_process.js:982:16)
    at Socket.stream.socket.on (internal/child_process.js:389:11)
    at Socket.emit (events.js:198:13)
    at Pipe._handle.close (net.js:606:12)
  killed: false,
  code: 1,
  signal: null,
  cmd:
   'gitleaks --repo=https://github.com/user/repo -v --username=foo --password=bar' 

我试图研究我的问题,看看我是否遗漏了什么并阅读:

nodejs exec command failing with no useful error message Node Child Process Exec Command Failed with error code 1 nodejs exec command fails for some windows commands with no clear error message NodeJS Child Process EXEC Command Failed with NVM Permission denied OSX

为什么我的exec 命令失败,但我可以在终端中传递相同的命令并且它有效?

【问题讨论】:

我检查了 gitleaks 的文档,它显示了以下退出代码:0:没有泄漏,1:存在泄漏,2:遇到错误。我想知道该命令是否为“存在泄漏”返回 1,但“exec”函数认为这是一个错误。直接在终端运行同样的命令,退出码是什么? 是的,这似乎是问题所在。当我在代码 1 下控制台记录 error 时,它会转储所有泄漏信息。猜猜这意味着我需要弄清楚如何将其作为响应而不是错误,然后解决它。 我的评论是否有资格作为答案?如果是这样,我可以将其添加为答案。 如果您编写问题的解决方案,我会用它作为答案(重写 exec 条件化为 1 的 error.code 并解决错误信息)。这将是一个更好的问答,或者我可以回答。这样,如果有人遇到与 gitleaks 相同的问题,他们可以看到问题和解决方案。只是我的想法。 【参考方案1】:

exec 函数运行命令时,它会检查该命令的退出代码。它假定 0 以外的退出代码是错误,因此在回调中传递错误。如果gitleaks 在回购中发现秘密,那么它会以代码 1 退出。

按照这些思路应该可以工作:

const  exec  = require("child_process")
const test = `gitleaks --repo=https://github.com/user/repo -v --username=foo --password=bar`

const execRun = (cmd) => 
  return new Promise((resolve, reject) => 
    exec(cmd, (error, stdout, stderr) => 
      if (error) 
        if (error.code === 1) 
          // leaks present
          resolve(stdout);
         else 
          // gitleaks error
          reject(error);
        
       else 
        // no leaks
        resolve(stdout);
      
    )
  )


(async () => 
try 
  const testing = await execRun(test)
  console.log(testing)
 catch (e) 
  console.log(e)

)()

【讨论】:

以上是关于为啥我的 exec 命令失败但如果命令在终端中传递则可以工作?的主要内容,如果未能解决你的问题,请参考以下文章

如何在php中打开终端窗口并执行命令?

exec命令

Linux 命令(226)—— exec 命令(builtin)

Linux 命令(226)—— exec 命令(builtin)

为啥我的 C++ 代码中出现链接器命令失败错误? [复制]

在终端上使用 xcodebuild 命令导出失败