Node.js中执行Curl导出命令无法保存文件的解决方法
解决Node.js中exec执行curl导出Sanity数据无文件无错误的问题
终端中直接执行curl命令能正常导出Sanity数据集到文件,但用Node.js的exec执行相同命令时既无文件生成也无错误提示,可从以下几个方向排查解决:
1. 先捕获错误信息,定位问题根源
exec默认不会主动抛出错误,必须添加回调函数才能获取执行过程中的错误或stderr输出,这是排查的第一步:
const { exec } = require('child_process'); exec( 'curl -H "Authorization: Bearer sknWtK4sRt..." "https://myproject.api.sanity.io/v2021-06-07/data/export/mydataset" > mydataexported.ndjson', (error, stdout, stderr) => { if (error) { console.error(`执行错误: ${error.message}`); return; } if (stderr) { console.error(`curl执行报错: ${stderr}`); return; } console.log(`导出内容: ${stdout}`); } );
2. 确认文件输出路径
exec的工作目录可能和你当前脚本的执行目录不一致,导致文件生成在你未注意的路径。可以改用绝对路径指定输出文件:
const { exec } = require('child_process'); const path = require('path'); // 生成当前脚本目录下的绝对路径 const outputFile = path.resolve(__dirname, 'mydataexported.ndjson'); exec(`curl -H "Authorization: Bearer sknWtK4sRt..." "https://myproject.api.sanity.io/v2021-06-07/data/export/mydataset" > ${outputFile}`);
3. 改用spawn替代exec
exec有输出缓冲区大小限制,当导出的数据集较大时可能静默失败。spawn更适合处理流数据,且能更精准控制进程:
const { spawn } = require('child_process'); const fs = require('fs'); const outputStream = fs.createWriteStream('mydataexported.ndjson'); // spawn的参数需拆分为数组,避免引号转义问题 const curl = spawn('curl', [ '-H', 'Authorization: Bearer sknWtK4sRt...', 'https://myproject.api.sanity.io/v2021-06-07/data/export/mydataset' ]); // 将curl的stdout管道到文件流 curl.stdout.pipe(outputStream); // 监听错误输出 curl.stderr.on('data', (data) => { console.error(`curl错误: ${data.toString()}`); }); // 监听进程退出 curl.on('close', (code) => { code === 0 ? console.log('导出成功完成') : console.error(`curl进程异常退出,代码: ${code}`); });
4. 直接用Node.js内置模块替代curl
在Node.js环境中,没必要依赖外部curl命令,用内置的https模块直接请求更可控,也避免了跨平台兼容性问题:
const https = require('https'); const fs = require('fs'); const outputStream = fs.createWriteStream('mydataexported.ndjson'); const options = { hostname: 'myproject.api.sanity.io', path: '/v2021-06-07/data/export/mydataset', headers: { 'Authorization': 'Bearer sknWtK4sRt...' } }; const req = https.get(options, (res) => { if (res.statusCode !== 200) { console.error(`请求失败,状态码: ${res.statusCode}`); res.resume(); // 消耗响应流避免内存泄漏 return; } // 将响应流写入文件 res.pipe(outputStream); outputStream.on('finish', () => { console.log('数据集导出完成'); }); }); req.on('error', (err) => { console.error(`请求出错: ${err.message}`); }); req.end();
内容的提问来源于stack exchange,提问作者Leonel Matias Domingos
相关产品推荐
相关产品推荐

