.BAT在完成各自的列表后分出多个嵌套循环 [英] .BAT break out of multiple nested loop, after finishing the respective list
问题描述
我知道从嵌套循环中解脱出来很容易,但是当我使用多个服务器列表的时候,我不知道该怎么做。这里是场景:
$ b 目标:在服务器上搜索匹配特定用户ID的会话,并且还可以终止找到的任何断开的会话。
问题:我有多个农场的列表。我希望在列表中循环,直到找到用户会话,然后在列表完成时停止(不清除会话时它们可能在场中有多个会话)。
Farmlist1.txt
farmlist2.txt
farmlist3.txt
如果在farmlist2.txt中找到会话,我想要在这个列表中完成搜索,但不要继续farmlist3.txt。
这是我到目前为止,它像一个魅力。 (欢迎使用优化)
$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ echo $ $ $ echo $ $ $ $ echo $。
echo这将查找一个特定的用户ID,并杀死所有服务器上断开连接的会话!
set / p userid =用户的用户ID:
for %% a in(q:\scripts\1common\citrixlists\ * .txt)do(
for /如果错误级别为1($ b $),则返回f(tokens = *%% l in(%% a)do(
ping %% l -n 1 | find / iTTL => nul
b回显服务器%% l下载或不加载
)else(
echo寻找%用户名%并杀死%% l
/ 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 / ftokens = 2%%我IN('qwinsta / server:%% l ^ | find / idisc')DO (
if %% i gtr 0(
rwinsta %% i / server:%% l&& amp; echo)断开连接的会话已终止
)
)
)
)
)
为循环打破一个很简单:put
goto:STOP
进入循环结构后面一行的标签:STOP
。下面的例子根据循环计数器的值来打破循环:
@echo off
for / L %% I in(0,1,5)do(
if %% I GTR 3(
echo Break!
goto:STOP
)
echo %% I
$ STOP b
$ b $ p $尽管循环被指定计数到<$ c
$ b $ 2
3
休息!
请注意,循环实际上是在内部完成计数,但是没有更多的命令被执行。您可以很容易地再现,当您增加最终值 5
到一个巨大的数字,如 1000000
。
但现在让我们集中讨论嵌套循环(每个示例中两个):
-
下面的代码片断会在满足一定条件时中断两个循环:
(Aa Bb Cc)do(
for / L %% I in(0,1,5)do(
如果%%〜J= =Bbif %% 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
休息!
正如您所看到的,循环结构的执行在某个时刻立即中断。
-
批处理文件在满足内部循环中的某个条件时,打破外部循环。检查结果通过变量
FLAG
传递给外部循环:
@echo off
setFLAG =
for %% J in(Aa Bb Cc)do(
for / L %% I in(0,1,5)do (
if%%〜J==Bbif %% I GTR 3(
echo Break!
setFLAG =#
)
echo %%〜J - %% I
)
如果已定义FLAG goto:STOP
)
:STOP
输出结果是:
$ $ $ $ $ $ $ $ $ $ $ $ $ A $ -1
Aa-2
Aa-3
Aa-4
Aa-5
Bb-0
Bb-1
Bb- 2
Bb-3
休息!
Bb-4
休息!
bb-5
您会注意到内部循环在外部循环之前完成执行打破。
-
当一定的条件是网络时,下面的脚本打破了内部循环。为了不破坏外层循环,需要一个子程序来保存内层循环,并从外层调用(
call
)来隐藏外层循环的代码块上下文从goto
分解方法:
@echo off $ b (
call:SUB%%〜J
)
goto:EOF
:SUB
for / L %% I in(0,1,5)do(
if%〜1==Bbif %% I GTR 3(
echo Break!
goto:STOP
)
echo%〜1 - %% I
)
:STOP
输出结果为:
$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ A $
aa-2
aa-3
aa-4
aa-5
Bb-0
Bb-1
Bb-2
Bb-3
休息!
Cc-0
Cc-1
Cc-2
Cc-3
Cc-4
Cc-5
$ c
$ b这里外层循环完成了它的执行,不受内部破坏的影响
我希望其中的一个(最后两个)例子适合您脚本的需求。
I know breaking out of a nested loop is fairly easy, however, I'm not sure how to do it when I'm working with multiple lists of servers. Here's the scenario:
Goal: Search for sessions on a server matching a specific user ID, and also kill any disconnected sessions found
Problem: I have multiple lists of farms. I want to cycle through the lists until I find the users session, and then stop when that list is finished (not stop when the session is cleared, they may have multiple sessions in the farm).
Farmlist1.txt farmlist2.txt farmlist3.txt
If the session is found in farmlist2.txt, I want to FINISH searching in that list, but don't continue to farmlist3.txt.
Here's what I have so far, and it works like a charm. (Optimizations welcomed)
@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:\scripts\1common\citrixlists\*.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
)
)
)
)
)
I do not exactly understand what you are trying to accomplish, but I do understand how to break out of nested for
loops (or any other nested parenthesised blocks of code). So let me elaborate on that.
Breaking a single for
loop is simple: put goto :STOP
into the loop and the label :STOP
in the line following the loop structure. The example below breaks the loop depending on its loop counter value:
@echo off
for /L %%I in (0,1,5) do (
if %%I GTR 3 (
echo Break!
goto :STOP
)
echo %%I
)
:STOP
Although the loop is specified to count up to 5
, the output is:
0
1
2
3
Break!
Note that the loop actually completes the counting internally, but no more commands are executed. You can easily reproduce that when you increase the end value 5
to a huge number like 1000000
.
But now let us concentrate on nested loops (two in each example):
The following code snippet breaks both loops upon a certain condition is met:
@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
The output is:
Aa-0 Aa-1 Aa-2 Aa-3 Aa-4 Aa-5 Bb-0 Bb-1 Bb-2 Bb-3 Break!
As you can see, execution of the loop construct is interrupted immediately at a certain point.
The batch file here breaks the outer loop when the a certain condition in the inner loop is met. The result of the check is transferred to the outer loop using a variable
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
The output is:
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
You will notice that the inner loop finishes execution before the outer one is broken.
The script below breaks the inner loop when a certain condition is net. To not break the outer loop, a sub-routine holding the inner loop and being called (
call
) from the outer one is required to hide the code block context of the outer loop from thegoto
break-up method:@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
The output is:
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
Here the outer loop finishes its execution without being affected by the broken inner one.
I hope one of the (last two) examples suits the requirements for your script.
这篇关于.BAT在完成各自的列表后分出多个嵌套循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!