node repl 不支持直接管道输入,需用 node -e、自定义脚本或子进程实现;-e 适合单行处理,脚本适合复杂逻辑,spawn 可桥接 repl 但非全自动。

Node REPL 本身不支持直接通过管道符(|)接收 Shell 的标准输入并持续交互执行——它不是设计为管道“过滤器”的程序,而是一个交互式读取-求值-打印循环环境。但你可以用几种明确、可靠的方式,把 Shell 的数据流接入 Node.js 并实现自动化 JS 处理,关键在于**绕过 REPL 的交互模式,改用脚本执行或子进程通信机制**。
用 node -e 执行单行 JS,配合 Shell 管道
这是最轻量、最符合“管道流”直觉的方式:Shell 数据通过 stdin 进入 Node.js 脚本,JS 代码一次性处理并输出结果。
-
echo "hello world" | node -e "console.log(require('fs').readFileSync(0, 'utf8').trim().toUpperCase())"→ 输出HELLO WORLD -
ps aux | head -5 | node -e "console.log(require('fs').readFileSync(0,'utf8').split(' ').map(l => l.split(/s+/)[10]).join('|'))"→ 提取前 5 行的第 11 列(COMMAND)并拼接 - 注意:
require('fs').readFileSync(0, ...)中的0指代标准输入(stdin),是跨平台安全的写法
写可复用的 .js 脚本,作为管道过滤器
比 -e 更清晰、可维护。脚本从 stdin 读取全部内容(或逐行读取),用 JS 处理后输出到 stdout。
- 新建
filter.js:const readline = require('readline');<br>const rl = readline.createInterface({ input: process.stdin });<br>rl.on('line', line => {<br> console.log(line.replace(/\d+/g, '[NUM]'));<br>}); - 使用:
echo "id=123 name=test" | node filter.js→ 输出id=[NUM] name=test - 优势:支持异步、模块导入、错误处理;可加
#!/usr/bin/env node直接设为可执行文件
用 child_process.spawn 启动独立 REPL 并桥接 stdin/stdout
若你确实需要“REPL 环境 + Shell 输入流”,需主动管理子进程 I/O,不能依赖默认 REPL 行为。
- 主脚本启动一个
node子进程,并将自身的process.stdin流式转发给它: const { spawn } = require('child_process');<br>const node = spawn('node', [], { stdio: ['pipe', 'inherit', 'inherit'] });<br>process.stdin.pipe(node.stdin); // 把键盘/管道输入传给子 REPL- 这样,
echo "2+2" | node bridge.js就会触发子 REPL 计算并打印4 - ⚠️ 注意:子 REPL 仍会响应
.exit、Ctrl+D等,不适合纯自动化;更适合调试桥接场景
避免常见误区
以下操作无法按预期工作,需特别留意:
-
echo "1+1" | node—— REPL 启动后等待交互输入,不会自动执行管道进来的字符串,会卡住 -
cat file.txt | node—— 同样进入交互模式,不读取 stdin 内容;必须显式调用readFileSync(0)或readline - 在
node -e中试图用readline创建多轮交互 —— 不适用,-e 是单次执行;需用完整脚本 - 忽略编码和换行:Shell 管道末尾常带
,JS 处理前建议.trim()或按行分割










