使用sudo-prompt以特权运行Node.js脚本无控制台输出问题
问题
当前环境:node@18.15.0、pnpm@8.6.5、sudo-prompt@9.2.1,需要以特权权限执行命令node ./test.cjs。无权限执行时脚本可正常运行并显示日志,但通过sudo-prompt执行后无法在终端看到console.log的输出。
对比场景:将webpack命令作为npm脚本("test": "webpack --config ./webpack/webpack.config.dev.ts"),执行sudo pnpm test(macOS环境)时,控制台可正常显示输出。
相关代码
test.cjs 文件内容
const sudoPrompt = require('sudo-prompt'); sudoPrompt.exec('node ./scripts/spawn-process.cjs', (error) => { if (error) { throw error; } });
scripts/spawn-process.cjs 文件内容
const { spawn } = require('node:child_process'); const spawner = spawn('webpack', ['--config', './webpack/webpack.config.dev.ts'], { windowsHide: true, shell: true, stdio: 'pipe', }); process.stdin.pipe(spawner.stdin); spawner.stdout?.on('data', (data) => { console.log(data); }); spawner.stderr?.on('data', (data) => { console.log(data); }); spawner.on('close', (exitCode) => { process.exit(exitCode); });
解决方案
1. 配置sudo-prompt的stdio选项
sudo-prompt默认不会继承父进程的stdio,需在exec方法中显式指定配置,让子进程输出传递到当前终端:
const sudoPrompt = require('sudo-prompt'); sudoPrompt.exec('node ./scripts/spawn-process.cjs', { stdio: 'inherit' }, (error) => { if (error) { throw error; } });
此配置会让sudo-prompt启动的子进程直接继承当前终端的标准输入、输出和错误流,webpack日志可直接显示在终端。
2. 调整spawn的stdio配置(可选)
若不想修改sudo-prompt配置,可将spawn的stdio改为'inherit',让webpack进程直接使用父进程的流:
const spawner = spawn('webpack', ['--config', './webpack/webpack.config.dev.ts'], { windowsHide: true, shell: true, stdio: 'inherit', });
这种方式下无需手动监听stdout和stderr事件,webpack输出会直接传递到终端。
3. 检查工作目录问题
sudo-prompt执行命令的工作目录可能与当前终端不一致,可显式指定命令绝对路径或在exec时配置cwd:
sudoPrompt.exec('node /你的项目绝对路径/scripts/spawn-process.cjs', { stdio: 'inherit', cwd: process.cwd() }, (error) => { if (error) { throw error; } });
内容的提问来源于stack exchange,提问作者Tal Rofe
相关产品推荐
相关产品推荐

