首页 > 解决方案 > 有没有一种安全的方法来防止 exec 剥离引号?

问题描述

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

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

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

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

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.

您可以在输出中看到它已去除引号。可能是其他东西在剥离,但我不知道是什么。

标签: javascriptnode.jsjsonnetlify

解决方案


不是exec,是壳。

您可以通过使用反斜杠转义每个引号(和反斜杠)来解决它:

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

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


推荐阅读