You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Shell脚本在Node.js中调用时行为不一致?

问题分析

原脚本的核心问题在于[ -t 0 ]的判断逻辑:在终端环境中,当没有输入时stdin是TTY设备,条件成立所以跳过base64;但Node.js的execFile调用时,stdin是一个未关闭的管道(而非TTY),此时! [ -t 0 ]为真,脚本会执行base64 -w 0,而base64会一直等待输入直到收到EOF,导致脚本卡住。

解决方案

我们需要替换TTY检测逻辑,改为直接检查stdin是否有可读数据,同时保证二进制数据(包括空字节)的处理兼容性。以下是修改后的脚本:

#!/bin/sh
# 尝试非阻塞读取1字节,失败则说明无输入
if data=$(dd if=/dev/stdin bs=1 count=1 iflag=nonblock 2>/dev/null); then
    # 读取到数据,将已读字节和剩余stdin一起传给base64
    printf "%s" "$data" | cat - /dev/stdin | base64 -w 0
else
    # 无输入,输出空
    echo -n ""
fi
代码解释
  • dd if=/dev/stdin bs=1 count=1 iflag=nonblock:用非阻塞模式读取1字节,若stdin无数据则立即失败返回非0状态码,避免无限等待。2>/dev/null屏蔽dd的错误输出(比如"Resource temporarily unavailable")。
  • 若读取成功,用printf "%s" "$data"输出已读的1字节(避免echo处理二进制数据时的问题),再通过cat - /dev/stdin将其与剩余stdin数据合并,最后传给base64 -w 0转换。
  • 若读取失败,直接输出空字符串,符合无输入时的需求。
验证说明
  • 该脚本兼容POSIX sh(Alpine的busybox sh完全支持),无需额外软件。
  • 支持包含空字节的二进制数据:dd和cat都是二进制安全的,不会截断或修改数据。
  • 在终端和Node.js execFile调用场景下行为一致:无输入时立即退出,有输入时正常转换为base64输出。

内容的提问来源于stack exchange,提问作者Forivin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 23:43:23