核心方法(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