为何bash的while read循环执行terraform import后提前终止?
问题原因与排查解决办法
核心原因
问题出在**terraform import会默认读取标准输入(stdin)**,而你的while read循环正是从stdin读取JSON数组内容。第一次调用函数时,循环输入源被正常消费;但第二次调用时,terraform import会抢占stdin的读取权,直接消耗掉循环后续需要读取的内容,导致read -r i无法获取下一行数据,循环直接退出。哪怕把命令放到子shell,只要没重定向stdin,依然会共享父进程的stdin,所以问题无法解决。
排查方法
- 验证stdin占用情况:在
terraform import前后添加lsof -p $$ | grep stdin(Linux环境),查看stdin的状态是否在命令执行后发生变化;或者用echo "Before: $(cat /proc/self/fd/0)"直接查看stdin剩余内容。 - 临时重定向stdin测试:将
terraform import修改为terraform import ... < /dev/null,如果循环能正常遍历,即可确认是stdin被占用导致的问题。 - 替换命令测试:把
terraform import换成不读取stdin的命令(比如echo "processing $i"),若循环恢复正常,就能锁定是目标命令的stdin读取行为引发的问题。 - 检查循环输入源:确认JSON数组是否通过管道传递给
while read(比如jq ... | while read i),这种管道场景下的stdin会被后续命令共享,更容易出现这类冲突。
解决办法
最直接的方案是给terraform import强制重定向stdin到空设备,避免它读取循环依赖的输入:
terraform import <你的资源类型> <你的资源ID> < /dev/null
另外,也可以将循环输入源保存到临时文件,彻底规避管道带来的stdin共享问题:
# 先把JSON数组内容写入临时文件 jq -r '.[]' your-input.json > /tmp/import-items.txt # 从临时文件读取执行循环 while read -r i; do terraform import ... "$i" done < /tmp/import-items.txt # 清理临时文件 rm /tmp/import-items.txt
内容的提问来源于stack exchange,提问作者Vetal
相关产品推荐
相关产品推荐

