在while循环中使用sqlcmd导致无限循环的原因探究
为何bash while循环中调用sqlcmd会触发无限循环?
问题根源
你的问题本质是sqlcmd会默认从标准输入(stdin)读取数据,而while循环的输入流(比如你用来循环的文件)会被sqlcmd继承,两者的输入流冲突导致了异常。
具体过程:
- 当你用
while read line; do ... done < 你的文件这种写法时,read命令会逐行从文件(此时作为stdin)读取内容。 - 第一次循环时,
read读取了文件的第一行到变量中,随后sqlcmd启动。sqlcmd会直接读取stdin中剩余的所有内容,甚至在读完文件内容后,它还会继续等待更多输入(因为它默认会一直读取直到遇到GO或EOF才执行并退出)。 - 此时bash的
read命令会陷入异常:它无法正确检测到stdin的EOF,反而会重复返回最后一次成功读取的内容(也就是第一行),导致循环无限执行。
关于字符数的特殊表现
你发现文件内容少于4字符时不会触发无限循环,这是因为sqlcmd的输入缓冲区特性导致的:
- 当内容不足4字符时,sqlcmd读取后会判定内容无效,直接退出,此时stdin的EOF被正确传递给
read命令,read读取失败,循环正常终止。 - 当内容超过3字符时,sqlcmd会尝试等待更多输入来构成有效指令,进而引发上述的
read异常,导致无限循环。
解决方法
你已经找到的方法是正确的:将sqlcmd的输入流重定向到/dev/null,让它不再读取while循环的stdin:
sqlcmd -S 你的服务器 -U 用户名 -P 密码 -Q "你的SQL语句" < /dev/null
另外也可以用-i参数指定SQL文件,避免sqlcmd从stdin读取数据。
内容的提问来源于stack exchange,提问作者Raindy
相关产品推荐
相关产品推荐

