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

Bash脚本执行ADB命令后提前退出循环的问题求助

Bash脚本执行ADB命令后提前退出循环的问题求助

问题根源

这个问题是Bash脚本里非常典型的标准输入流抢占问题,很多和adb、ssh这类默认会读取标准输入的命令行工具配合循环读取文件时,都会碰到这个坑。

你的循环是通过done < $PurgeFile把目标文件的内容作为while read的标准输入(stdin),而adb命令默认会从stdin读取内容。当在循环里执行adb shell ...时,它会把原本要留给read -r CURRENT_LINE的剩余文件内容全部“吸走”,导致下一次read没有内容可读,循环直接提前终止——这和ADB命令执行成功还是失败完全无关,只要它触发了stdin读取就会出问题。

快速修复方案

给你两种简单可靠的解决办法,任选其一就能解决问题:

方案1:给ADB命令重定向标准输入

让adb不要读取循环的stdin,把它的输入重定向到/dev/null(空设备),这样就不会抢占循环的输入流了。把你脚本里的ADB命令行改成下面这样:

adb shell pm uninstall --user 0 $CURRENT_LINE < /dev/null || true

替换完成后再执行脚本,循环就能正常遍历完文件里的每一行,逐个处理所有包名了。

方案2:换一种文件读取方式

用cat命令读取文件内容,再通过管道传给while循环。这种方式下,循环的输入流和ADB的输入流是相互独立的,不会出现抢占冲突。修改你脚本的循环部分:

LINE=1
# 用cat管道替代直接重定向到done
cat "$PurgeFile" | while read -r CURRENT_LINE
do
    if [[ $CURRENT_LINE != "" ]]
    then
        echo "attempting to remove: $LINE: $CURRENT_LINE"
        adb shell pm uninstall --user 0 $CURRENT_LINE || true
    fi
    echo "Made it here"
    ((LINE++))
    echo "Made it to outer loop"
done

⚠️ 小提醒:这种管道方式有个小副作用——循环内部的变量(比如$LINE)在循环结束后不会保留它的最终值,但对你这个脚本的核心功能没有影响。

为什么注释ADB命令就正常?

当你把ADB命令注释掉后,循环内部没有其他命令会读取stdin,read -r CURRENT_LINE就能逐行读取文件内容,自然能完整遍历整个文件,所有调试输出也都正常。

验证效果

用方案1修改后,再执行脚本,就能看到脚本会逐个处理文件里的所有非空行,不管ADB卸载成功还是失败,循环都会一直跑直到文件末尾,完全符合你的预期。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 09:29:50