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

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

额外优化建议

  1. 查询用户后先检查文件是否为空,避免空循环
  2. 删除用户前先判断用户是否存在,避免不必要的报错:
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
  1. 执行完删除后删除临时文件"$item".txt,避免残留数据影响下次执行

内容的提问来源于stack exchange,提问作者microset

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 23:40:23