我知道打破嵌套循环相当容易,但是,当我使用多个服务器列表时,我不知道如何做到这一点。这是一个场景:
目标:在服务器上搜索与特定用户ID匹配的会话,并杀死找到的任何断开连接的会话
问题:我有多个农场列表。我想在列表中循环,直到找到用户会话,然后在列表结束时停止(而不是在会话被清除时停止,他们可能在服务器场中有多个会话)。
农场列表1.textfarmlist2.txtfarmlist3.txt
如果会话在farmlist2.txt中找到,我想在该列表中完成搜索,但不要继续到farmlist3.txt。
这是我迄今为止所拥有的,它就像一种魅力。(欢迎优化)
@echo off
echoCitrix Session Reset
echo.
echo This will look for a specific userID AND kill disconnected sessions on all servers!
set /p userid=User ID of the user:
for %%a in (q:scripts1commoncitrixlists*.txt) do (
for /f "tokens=*" %%l in (%%a) do (
ping %%l -n 1 | find /i "TTL=" > nul
if errorlevel 1 (
echo server %%l down or out of Load
) else (
echo Looking for %username% and killing disconnected sessions on %%l
for /f "tokens=3" %%b in ('qwinsta *tcp /server:%%l ^| find /i "%userid%"') do echo %%b | rwinsta %%b /server:%%l && echo SESSION FOR %userid% KILLED ON %%l
for /f "tokens=2" %%i IN ('qwinsta /server:%%l ^| find /i "disc"') DO (
if %%i gtr 0 (
rwinsta %%i /server:%%l && echo Disconnected sessions terminated
)
)
)
)
)
我不完全理解您想要实现的目标,但我确实理解如何突破嵌套的for
循环(或任何其他嵌套的带括号的代码块)。因此,让我详细阐述一下。
断开单个for
循环很简单:将goto :STOP
放入循环中,并在循环结构后面的行中标记:STOP
。以下示例根据循环计数器值中断循环:
@echo off
for /L %%I in (0,1,5) do (
if %%I GTR 3 (
echo Break!
goto :STOP
)
echo %%I
)
:STOP
尽管循环被指定为计数到5
,但输出为:
0
1
2
3
Break!
请注意,循环实际上在内部完成了计数,但不再执行任何命令。当您将结束值5
增加到像1000000
这样的巨大数字时,您可以很容易地重现这一点。
但现在让我们集中讨论嵌套循环(每个示例中有两个):
以下代码片段在满足特定条件时中断两个循环:
@echo off for %%J in (Aa Bb Cc) do ( for /L %%I in (0,1,5) do ( if "%%~J"=="Bb" if %%I GTR 3 ( echo Break! goto :STOP ) echo %%J-%%I ) ) :STOP
输出为:
Aa-0 Aa-1 Aa-2 Aa-3 Aa-4 Aa-5 Bb-0 Bb-1 Bb-2 Bb-3 Break!
正如您所看到的,循环构造的执行在某一点上会立即中断。
当满足内部循环中的某个条件时,这里的批处理文件会中断外部循环。使用变量
FLAG
:将检查结果传输到外循环@echo off set "FLAG=" for %%J in (Aa Bb Cc) do ( for /L %%I in (0,1,5) do ( if "%%~J"=="Bb" if %%I GTR 3 ( echo Break! set "FLAG=#" ) echo %%~J-%%I ) if defined FLAG goto :STOP ) :STOP
输出为:
Aa-0 Aa-1 Aa-2 Aa-3 Aa-4 Aa-5 Bb-0 Bb-1 Bb-2 Bb-3 Break! Bb-4 Break! Bb-5
您会注意到,内部循环在外部循环中断之前完成了执行。
当某个条件为net时,下面的脚本会中断内部循环。为了不破坏外循环,需要一个保持内循环并从外循环调用(
call
)的子程序,以从goto
分解方法中隐藏外循环的代码块上下文:@echo off for %%J in (Aa Bb Cc) do ( call :SUB "%%~J" ) goto :EOF :SUB for /L %%I in (0,1,5) do ( if "%~1"=="Bb" if %%I GTR 3 ( echo Break! goto :STOP ) echo %~1-%%I ) :STOP
输出为:
Aa-0 Aa-1 Aa-2 Aa-3 Aa-4 Aa-5 Bb-0 Bb-1 Bb-2 Bb-3 Break! Cc-0 Cc-1 Cc-2 Cc-3 Cc-4 Cc-5
在这里,外循环完成了它的执行,而不受损坏的内循环的影响。
我希望(最后两个)示例中的一个适合您的脚本要求。