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

Bash实现类Python生成器及解决生成值过量未消费问题

Bash 类Python生成器的实现与阻塞优化方案

初始实现思路

最初探索到的基于进程替换的类生成器写法结构如下:

#!/usr/bin/env bash
{
    # 主代码,注意此处运行在主线程,使用管道实现则不具备该特性
    ...
    IFS= read -d '' -r VALUE  # 等价于Python中的next()
    ...
} < <(
    # 字符串生成器
    ...
    printf "%s\0" "$VALUE"  # 等价于Python中的yield
    ...
)

典型使用场景如下,该写法的核心优势是保持主逻辑简洁:

LINK_NAME="$DIR/$(basename "$FILE")"
while [ -e "$LINK_NAME" ] && [ "$(readlink "$LINK_NAME")" != "$TARGET" ]; do
    IFS= read -d '' -r LINK_NAME
done < <(
    printf "%s\0" "$DIR/Link to $(basename "$FILE")"
    printf "%s\0" "$DIR/Another link to $(basename "$FILE")"
    declare -i COUNT=3
    while true; do
        case $COUNT in
            *1?) ORD="th";;
             *1) ORD="st";;
             *2) ORD="nd";;
             *3) ORD="rd";;
              *) ORD="th";;
        esac
        printf "%s\0" "$DIR/$COUNT$ORD link to $(basename "$FILE")"
        COUNT+=1
        
        echo "[generated $COUNT]" >&2  # Debug
        ((COUNT>=100)) && break        # 安全退出条件
    done
)

存在的问题

初始实现存在生成器预先生成大量超出实际需要的数值的问题,主程序运行速度越慢问题越明显。预期中printf输出未被消费时应当阻塞,但实际没有达到该效果。
尝试过对printf使用stdbuf -o0或stdbuf -oL关闭缓冲,没有生效。也无法对整个生成器使用stdbuf,因为它不是独立的可执行程序,同时也不希望将生成器拆分为单独文件破坏代码简洁性。

最终解决方案

通过coproc协同进程加两个工具函数的方式解决了阻塞问题,代码保持了较高的简洁度,实现如下:

#!/usr/bin/env bash
yield() { read -r; printf "%s\0" "$*"; }
next() { local _N _P="$1[1]"; echo >&"${!_P}"; _P="$1[0]"; IFS= read -d '' -r ${2-_N} <&"${!_P}"; (($#<2)) && echo -n "$_N"; }

coproc generator (
    ...
    yield "$VALUE"
    ...
)
# 主代码
...
VALUE="$(next generator)"
# 也可以使用该写法
next generator VALUE
...

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 03:36:03