有没有一种安全的方法可以防止exec删除引号?

时间:2019-10-30 12:41:01

标签: javascript node.js json netlify

我想通过节点的子进程exec方法运行一个命令,该方法将包含一个JSON字符串,该字符串本身将包含引号字符。看起来exec默认会删除它们。有办法防止这种情况吗?

我正在尝试在netlify中自动创建构建挂钩,这是我们目前正在尝试进行的一些自动化QA的一部分。目前,我正在使用netlify cli(特别是他们的netlify api createSiteBuildHook方法)来进行此操作。我想捕获此命令的输出以及向命令中注入一些数据,因此我尝试使用节点的子进程exec()命令来解决此问题。我在这里遇到的问题是netlify命令期望将JSON字符串用作该命令的参数,并且事实证明,exec默认情况下会删除引号,出于安全原因,我推测是。我希望有办法解决这个问题。

我尝试过并考虑过的一些替代方法:

  • 我之前曾尝试使用netlify api js客户端解决此问题,但是我们一直在自动刷新api令牌方面遇到问题。这是CircleCI中自动构建过程的一部分,因此可以从任何交互中抽象出来。我想避免开发人员每次构建和自动测试停止工作时都必须手动进行更新,因为我们已经超出了速率限制或其他限制。
  • 我尝试使用转义的引号,例如\"^"等。
  • 我尝试使用诸如spawn或execFile的替代子进程方法,但似乎遇到了同样的问题。
  • 最后的选择是将其完全抽象为bash。这不是完全不可行的,只会变得很烦人。我必须将输出保存在文件中,然后加载该文件并在要获取新生成的构建钩子的URL时对其进行审问。如果我可以在JS中完成此工作,则可以节省很多时间。

我用来生成构建挂钩的命令:

yarn netlify api createSiteBuildHook -d {"site_id":"my-site-id","body":{"title":"my-title","branch":"my-branch"}}

我用于通过exec运行此代码的代码:

yargs
  .command(
    'createBuildHook',
    'Creates a build hook in netlify',
    {},
    async () => {
      const buildHookRequest = JSON.stringify({
        site_id: process.env.NETLIFY_MASTER_ID,
        body: {
          title: branchName(),
          branch: branchName(),
        }
      });

      const cmd = exec(`yarn netlify api createSiteBuildHook -d ${buildHookRequest}`, (err, stout) => {
        if (err) {
          console.log(`Error: ${err}`); 
        }
        console.log(`Output: ${stout}`);
      });
    }
  )
  .demandCommand().argv;

我尝试运行命令时遇到的错误:

$ yarn qa-automate:createBuildHook
yarn run v1.16.0
$ yarn qa-automate createBuildHook
$ babel-node --presets @babel/preset-env -- ./qa-automation/cli.js createBuildHook
Error: Error: Command failed: yarn netlify api createSiteBuildHook -d {"site_id":"my-site-id","body":{"title":"my-title","branch":"my-branch"}}
SyntaxError: Unexpected token s in JSON at position 1
    at JSON.parse (<anonymous>)
    at APICommand.run (C:/Users/owen_jones/web-work/website-assets/node_modules/netlify-cli/src/commands/api.js:45:61)
error Command failed with exit code 1.

Output: $ C:\Users\owen_jones\web-work\website-assets\node_modules\.bin\netlify api createSiteBuildHook -d {site_id:my-site-id,body:{title:my-title,branch:my-branch}}
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Done in 3.92s.

您可以在输出中看到它已经去除了引号。可能是其他原因在进行剥离,但我无法解决。

1 个答案:

答案 0 :(得分:1)

不是exec,而是外壳。

您可以通过在每个引号(和反斜杠)之间加上反斜杠来解决此问题:

const cmd = exec(`yarn netlify api createSiteBuildHook -d ${buildHookRequest.replace(/[\\"]/g, "\\$&")}`, (err, stout) => {

这可能不是强大的通用解决方案,但对于您正在做的事情可能已经足够了。 (我的快速本地测试足够通过JSON了。)