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

Bash While循环中逐行执行脚本仅运行一次的问题及解决方法

问题分析与解决:while循环仅执行一次的原因

你的脚本循环只跑一次的核心原因是:source 加载的quality-test.sh会继承当前shell的标准输入(也就是你用来读取parameters.txt的输入流)。如果quality-test.sh内部有任何读取标准输入的操作(哪怕是某些命令默认读取stdin的隐性行为),它会一次性把parameters.txt里剩下的所有行都读走,导致外层的read再也拿不到后续内容,循环直接终止。

下面是几种可行的解决方法:

方法1:给source的脚本重定向标准输入

让quality-test.sh的标准输入指向/dev/null,这样它就不会去读取parameters.txt的内容了:

BITRATE=
QUALITY=

while read -r BITRATE QUALITY; do
        source ./quality-test.sh -b "$BITRATE" -q "$QUALITY" < /dev/null
done < parameters.txt

方法2:直接执行脚本而非source

既然单独运行./quality-test.sh完全正常,没必要用source。直接执行会启动子shell,不会占用当前shell的输入流,自然不会干扰循环的读取:

BITRATE=
QUALITY=

while read -r BITRATE QUALITY; do
        ./quality-test.sh -b "$BITRATE" -q "$QUALITY"
done < parameters.txt

如果之前用source是为了共享环境变量,可以改成让quality-test.sh将结果输出到文件,或者通过其他方式传递数据,避免依赖当前shell环境。

方法3:用独立文件描述符保护输入流

把parameters.txt绑定到一个单独的文件描述符(比如3),让read从这个描述符读取内容,这样主stdin不会被内部脚本影响:

BITRATE=
QUALITY=

while read -r BITRATE QUALITY <&3; do
        source ./quality-test.sh -b "$BITRATE" -q "$QUALITY"
done 3< parameters.txt

补充说明

你之前尝试的(...)子shell方式没用,是因为子shell默认继承父shell的stdin,只要quality-test.sh读stdin,还是会把剩下的行消耗掉。如果一定要用子shell,也要在子shell里给quality-test.sh重定向stdin到/dev/null才行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 14:43:13