.BAT在完成各自的列表后分出多个嵌套循环 [英] .BAT break out of multiple nested loop, after finishing the respective list

查看:254
本文介绍了.BAT在完成各自的列表后分出多个嵌套循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道从嵌套循环中解脱出来很容易,但是当我使用多个服务器列表的时候,我不知道该怎么做。这里是场景:
$ 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






但现在让我们集中讨论嵌套循环(每个示例中两个):


  1. 下面的代码片断会在满足一定条件时中断两个循环:

      (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
    休息!

    正如您所看到的,循环结构的执行在某个时刻立即中断。


  2. 批处理文件在满足内部循环中的某个条件时,打破外部循环。检查结果通过变量 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

    您会注意到内部循环在外部循环之前完成执行打破。


  3. 当一定的条件是网络时,下面的脚本打破了内部循环。为了不破坏外层循环,需要一个子程序来保存内层循环,并从外层调用( 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

    $ 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):

  1. 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.

  2. 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.

  3. 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 the goto 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆