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

如何实现流式Shell命令执行器,使命令捕获自身标准输入?

Shell脚本行为差异与命令流执行器实现

两种脚本的行为差异

1. 嵌套sh的here-doc脚本(script.sh)

脚本代码:

#!/bin/sh
sh <<EOF
cat | xargs -n 1 echo captured
echo first
echo second
EOF

执行后,cat会捕获here-doc内的后续命令流而非外部输入,输出如下:

captured echo
captured first
captured echo
captured second

即使通过echo input | script.sh调用,结果完全一致。

2. 普通脚本(script-plain.sh)

脚本代码:

#!/bin/sh
cat | xargs -n 1 echo captured
echo first
echo second

执行echo input | script-plain.sh时,cat会读取外部传入的stdin,输出如下:

input
first
second

需求说明

需实现executor.sh,通过curl some-streaming-endpoint获取持续输出的命令流(示例内容:echo ping 1、cat、echo ping 2...echo ping n),满足以下要求:

  • 命令流中的echo命令正常执行并输出对应内容;
  • 命令流中的cat命令捕获executor.sh的外部stdin(如echo "data 1\ndata 2"传入的内容);
  • 禁止使用临时文件存储命令流(因流为持续输出)。

执行echo "data 1\ndata 2" | ./executor.sh需输出:

ping 1
data 1
data 2
ping 2
ping 3
...
ping n

实现方案

以下是executor.sh的代码:

#!/bin/sh
# 将外部stdin复制到文件描述符3保存
exec 3<&0

# 持续读取命令流并逐行处理
curl some-streaming-endpoint | while read -r cmd; do
    case "$cmd" in
        cat)
            # cat命令从保存的外部stdin读取内容
            cat <&3
            ;;
        *)
            # 其他命令直接执行
            eval "$cmd"
            ;;
    esac
done

# 关闭文件描述符3
exec 3<&-

代码说明

  1. 保存外部输入:通过exec 3<&0把外部传入的stdin复制到文件描述符3,避免命令流占用主stdin后无法读取外部输入;
  2. 流式处理命令:用while read -r cmd逐行读取curl返回的持续命令流,无需缓存全部内容;
  3. 命令分支处理:
    • 遇到cat时,直接从文件描述符3读取外部输入并输出,确保符合需求;
    • 其他命令通过eval执行,保证echo等命令正常输出内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 09:52:28