如何阻止Node.js exec移除JSON字符串中的引号?
解决Node.js exec执行带JSON参数的Netlify命令时引号丢失的问题
这个问题的核心是shell解析命令时会移除JSON字符串中的双引号,导致Netlify CLI收到的参数无法被正确解析为JSON。下面给你两种可靠的解决方案:
方案1:使用execFile传递参数数组(推荐)
exec方法会把整个命令字符串交给系统shell解析,而shell会把双引号当作参数分隔符处理并移除。改用execFile并通过参数数组传递命令和参数,可以绕过shell的解析,让每个参数原封不动地传递给子进程。
修改你的代码如下:
const { execFile } = require('child_process'); const yargs = require('yargs'); 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(), } }); // 使用execFile,参数以数组形式传递 execFile('yarn', [ 'netlify', 'api', 'createSiteBuildHook', '-d', buildHookRequest ], (err, stdout) => { if (err) { console.log(`Error: ${err}`); return; } console.log(`Output: ${stdout}`); }); } ) .demandCommand().argv;
这种方式不需要处理任何引号转义,参数会被完整传递,完全避免shell解析带来的问题。
方案2:给JSON字符串包裹单引号并转义内部特殊字符
如果坚持使用exec,可以把生成的JSON字符串用单引号包裹,让shell把整个JSON识别为一个单独的参数:
const cmd = exec(`yarn netlify api createSiteBuildHook -d '${buildHookRequest}'`, (err, stdout) => { // 处理逻辑 });
不过要注意:如果你的JSON内容中包含单引号,这种方法会失效,需要额外转义单引号(比如把'替换为'\'')。因此这种方法不如方案1通用。
为什么你之前的尝试没生效?
- 转义引号无效:你可能直接使用了
"或^"转义,但在JS字符串中,要让shell识别转义的双引号,需要写成\\"(JS中\需要转义为\\),比如buildHookRequest.replace(/"/g, '\\"'),但这种方式容易出错,不如参数数组可靠。 - spawn/execFile仍有问题:大概率是你使用时还是把参数拼进了命令字符串,而非使用数组传递参数。只要用数组传递,就不会有引号丢失的问题。
内容的提问来源于stack exchange,提问作者OwenJones
相关产品推荐
相关产品推荐

