Bash中while循环读取文件仅处理首行,rsync加--dry-run却运行正常
问题根本原因
该问题的核心是标准输入(stdin)被循环内执行的命令抢占读取:
- 你使用的
while read循环默认从stdin读取/tmp/quarantine.list的内容,循环内调用的所有命令都会默认继承这个stdin输入源。 - 当rsync不带
--dry-run参数实际执行传输、以及后续调用ssh执行远程清理时,两个命令都会主动读取stdin的内容,导致列表文件第一行之后的所有内容被rsync/ssh当作自身输入吃掉,read命令无法拿到后续行,循环直接终止。 - 当rsync加上
--dry-run参数时,仅做模拟执行不需要实际传输交互,不会读取stdin,因此read可以正常读取所有行,循环可以完整执行。
修复方案
可以任选以下一种方法修复:
- 强制循环内的rsync、ssh从空设备读取输入,避免抢占循环的输入内容,只需在两个命令末尾追加
</dev/null即可:
while IFS= read -r server_alias; do # 备份逻辑,rsync末尾加</dev/null rsync [你的其他rsync参数] "${server_alias}:[远程路径]" [本地路径] </dev/null # 清理逻辑,ssh末尾加</dev/null ssh "${server_alias}" [你的清理命令] </dev/null # 日志记录逻辑 done < /tmp/quarantine.list
- 将列表文件绑定到自定义文件描述符读取,完全和stdin隔离:
# 用文件描述符3读取列表文件,和stdin完全独立 while IFS= read -r server_alias <&3; do # 循环内逻辑不需要额外修改 rsync [你的其他rsync参数] "${server_alias}:[远程路径]" [本地路径] ssh "${server_alias}" [你的清理命令] # 日志记录逻辑 done 3< /tmp/quarantine.list
内容的提问来源于stack exchange,提问作者Liso
相关产品推荐
相关产品推荐

