Bash脚本执行sqlcmd删除用户时陷入无限循环求助
问题:Bash脚本执行sqlcmd删除用户时陷入无限循环
原脚本代码
#!/bin/sh sqlserver=("localhost" "testserver") db="master" user="sa" pass="test@12345" for item in "${sqlserver[@]}" do sqlcmd -S "$item" -d $db -U $user -P $pass -I -h-1 -Q "set nocount on;SELECT name as username FROM SYSUSERS WHERE NAME LIKE '%test%'" >> "$item".txt while IFS= read -r line; do if [ -n "$line" ] then #echo "Text read from file: $line" sqlcmd -S "$item" -d $db -U $user -P $pass -I -b -h-1 -Q "set nocount on;drop user $line" fi done < "$item".txt done
报错信息
Msg 15151, Level 16, State 1, Server 66752ccaf826, Line 1 Cannot drop the user 'test2', because it does not exist or you do not have permission. ...
补充说明
- 使用
echo "Text read from file: $line"时,if条件可正常执行,循环能正常结束 - 替换为删除用户的sqlcmd命令后,脚本陷入无限循环
- 测试用用户创建语句:
CREATE USER test1 WITHOUT LOGIN; CREATE USER test2 WITHOUT LOGIN;
- 需求:读取完文件后终止循环,继续处理下一个SQL Server实例
问题原因
sqlcmd默认会从标准输入读取数据,而while read循环是以"$item".txt作为标准输入来源。当在循环内执行sqlcmd时,它会抢占这个输入流,导致read命令无法正确读取文件内容,进而陷入无限循环。同时,循环重复执行删除命令,已被删除的用户再次删除就会抛出15151错误。
解决方法
将循环内的sqlcmd命令的标准输入重定向到/dev/null,避免它占用while read的输入流。修改后的脚本如下:
#!/bin/sh sqlserver=("localhost" "testserver") db="master" user="sa" pass="test@12345" for item in "${sqlserver[@]}" do sqlcmd -S "$item" -d $db -U $user -P $pass -I -h-1 -Q "set nocount on;SELECT name as username FROM SYSUSERS WHERE NAME LIKE '%test%'" >> "$item".txt while IFS= read -r line; do if [ -n "$line" ] then sqlcmd -S "$item" -d $db -U $user -P $pass -I -b -h-1 -Q "set nocount on;drop user $line" < /dev/null fi done < "$item".txt done
额外优化建议
- 查询用户后先检查文件是否为空,避免空循环
- 删除用户前先判断用户是否存在,避免不必要的报错:
sqlcmd -S "$item" -d $db -U $user -P $pass -I -h-1 -Q "set nocount on;SELECT COUNT(*) FROM SYSUSERS WHERE NAME = '$line'" < /dev/null | grep -q 1 && sqlcmd -S "$item" -d $db -U $user -P $pass -I -b -h-1 -Q "set nocount on;drop user $line" < /dev/null
- 执行完删除后删除临时文件
"$item".txt,避免残留数据影响下次执行
内容的提问来源于stack exchange,提问作者microset
相关产品推荐
相关产品推荐

