为何命令行jq通配符在Node.js spawnSync中失效?如何适配?
问题原因解析
命令行里的*.json通配符是由**系统Shell(如bash、zsh)**负责解析展开的:Shell会先把reports/jest/*.json替换成该目录下所有匹配的具体文件名,再将这些文件名传给jq程序,所以命令行能正常工作。
而Node.js的cp.spawnSync默认是直接启动jq程序,不会经过Shell中转,此时*.json会被当作一个字面量的文件名直接传给jq,自然找不到名为*.json的文件,因此报错。
解决方法
方法1:开启Shell解析选项
在spawnSync的配置参数中设置shell: true,让Shell先处理通配符展开,再调用jq:
const cp = require('child_process'); const configPath = 'config/jest.jq'; const folderPath = 'reports/jest/*.json'; const result = cp.spawnSync('jq', ['-f', configPath, '-s', folderPath], { shell: true });
这种方式和命令行的执行逻辑完全一致,简单直接。
方法2:手动展开通配符(跨平台更可控)
用Node.js原生模块或第三方包匹配目标文件,再将所有具体文件名传给jq:
原生模块实现(无需额外依赖)
const cp = require('child_process'); const fs = require('fs'); const path = require('path'); const configPath = 'config/jest.jq'; const targetDir = 'reports/jest'; // 筛选目录下所有.json文件并拼接完整路径 const jsonFiles = fs.readdirSync(targetDir) .filter(file => file.endsWith('.json')) .map(file => path.join(targetDir, file)); // 将所有文件作为参数传入jq const result = cp.spawnSync('jq', ['-f', configPath, '-s', ...jsonFiles]);
用glob包实现(更灵活,支持复杂匹配规则)
先安装依赖:
npm install glob
再编写代码:
const cp = require('child_process'); const glob = require('glob'); const configPath = 'config/jest.jq'; const filePattern = 'reports/jest/*.json'; // 匹配所有符合规则的文件 const jsonFiles = glob.sync(filePattern); const result = cp.spawnSync('jq', ['-f', configPath, '-s', ...jsonFiles]);
这种方式不依赖系统Shell,跨平台兼容性更好,且支持更复杂的文件匹配规则。
内容的提问来源于stack exchange,提问作者logicOnAbstractions
相关产品推荐
相关产品推荐

