核心方法(Node.js环境)
child_process.exec()
适用于执行简单命令并获取完整输出:
const { exec } = require('child_process'); exec('dir', (error, stdout, stderr) => { if (error) { console.error(`执行错误: ${error}`); return; } console.log(`输出结果: ${stdout}`); // 输出命令结果 if (stderr) console.error(`错误信息: ${stderr}`); });
child_process.spawn()
适合处理大量输出或实时流数据:
const { spawn } = require('child_process'); const ls = spawn('ls', ['-lh', '/usr']); // Linux/Mac示例 ls.stdout.on('data', (data) => { console.log(`实时输出: ${data}`); }); ls.stderr.on('data', (data) => { console.error(`错误流: ${data}`); }); ls.on('close', (code) => { console.log(`子进程退出码: ${code}`); });
child_process.execSync()(同步操作)
阻塞式执行,适用于脚本任务:
const { execSync } = require('child_process'); try { const result = execSync('echo "Hello, CMD!"'); console.log(result.toString()); // 输出: Hello, CMD! } catch (error) { console.error(error.message); }
安全风险与防御措施
-
命令注入攻击
危险示例:const userInput = '恶意命令; rm -rf /'; exec(`ls ${userInput}`); // 可能删除系统文件!
解决方案:使用参数化传递或严格过滤:
const { spawn } = require('child_process'); const safeInput = '正常目录'; const ls = spawn('ls', [safeInput]); // 安全:参数作为数组传递
-
权限最小化
- 避免使用
root
权限运行Node.js进程 - 通过
chroot
或容器隔离环境
- 避免使用
浏览器端替代方案
浏览器无法直接执行系统命令,但可通过以下方式间接交互:
- WebSocket连接后端服务
浏览器 → 发送请求 → Node.js服务器 → 执行命令 → 返回结果 - WebAssembly (WASM)
在沙箱中运行C/C++编译的命令行工具(如FFmpeg)
适用场景对比
方法 | 适用场景 | 是否异步 | 输出处理 |
---|---|---|---|
exec() |
简单命令,输出量小 | 是 | 一次性返回 |
spawn() |
实时流数据(日志/大文件) | 是 | 流式传输 |
execSync() |
同步任务(如启动脚本) | 否 | 直接返回结果 |
关键注意事项
-
路径处理
使用path.join()
避免跨平台路径问题:const path = require('path'); const dirPath = path.join(__dirname, 'docs'); exec(`ls ${dirPath}`);
-
超时控制
防止进程卡死:exec('长时间任务', { timeout: 5000 }, (error) => { if (error?.killed) console.log('进程超时终止'); });
-
环境变量
传递自定义环境变量:exec('echo $API_KEY', { env: { ...process.env, API_KEY: '12345' } });
在Node.js中执行命令行需通过child_process
模块,优先选择spawn()
处理流式数据,始终防范命令注入风险,浏览器端需通过服务端中转实现类似功能,生产环境中务必添加权限控制、日志监控和错误处理。
引用说明:
- Node.js官方文档 child_process模块
- OWASP命令注入防御指南 Command Injection
- Linux系统权限管理手册 Linux Permissions
原创文章,发布者:酷番叔,转转请注明出处:https://cloud.kd.cn/ask/6390.html