gpt4 book ai didi

powershell - 使用start子命令为循环改进批处理文件

转载 作者:行者123 更新时间:2023-12-03 00:25:49 25 4
gpt4 key购买 nike

我目前有一个非常简单的脚本,可以ping 10个IP:

@ECHO OFF
for /L %%i in (100, 1, 110) DO (
START /W /B cmd /c ping -n 1 192.168.0.%%i | find "time="
)

输出是预期的:
C:\Users\herpderp>test.batReply from 192.168.0.101: bytes=32 time=294ms TTL=64Reply from 192.168.0.104: bytes=32 time=1ms TTL=64

However, it is VERY slow and definitely happening sequentially. When I run this with a PowerShell Measure-Command I get these results:

PS C:\Users\derpherp> measure-command {start-process test.bat -Wait}Days              : 0Hours             : 0Minutes           : 0Seconds           : 23Milliseconds      : 107Ticks             : 231074173TotalDays         : 0.000267446959490741TotalHours        : 0.00641872702777778TotalMinutes      : 0.385123621666667TotalSeconds      : 23.1074173TotalMilliseconds : 23107.4173

So we see it is taking ~23 seconds to execute.

Now, if I were on a Linux system and wanted to do this same thing, I can do the following:

#!/bin/bash

for ip in $(seq 100 110); do
ping -c 1 192.168.0.$ip | grep "bytes from" | cut -d" " -f4 | cut -d ":" -f1 &
done

结果在多种方面有所不同:
  • 结果并不总是顺序的,这意味着它实际上以更异步的方式启动了命令:
    root@kali:~/vids/bash_scripting# ./test.sh192.168.0.104192.168.0.100192.168.0.103192.168.0.101
  • The time for it to display all of the positive results is typically less than a second and this scales to much larger sets of numbers.

  • So, my question, is this a limitation of batch scripting? I find it hard to believe that bash performs literally 100s of times better than Windows CMD interpreter for such a simple task?

    If this is limited, does PowerShell offer a competitive way to create tasks? I've used Start-Job in a foreach loop but that seems to become unworkable for large numbers of tasks (ie Test-Connection on a /16 network)

    Edit 1

    @ECHO OFF
    for /L %%i in (100, 1, 110) DO (
    ping -n 1 192.168.0.%%i | find "time="
    )

    这将输出当前窗口并花费与初始变体一样长的时间
    @ECHO OFF
    for /L %%i in (100, 1, 110) DO (
    START ping -n 1 192.168.0.%%i | find "time="
    )

    这将输出到每个IP的唯一窗口,并且只需花费很长时间即可完成。

    最佳答案

    异步并不是一件容易的事,但是使用PowerShell,您可以很轻松地完成工作。

    此代码的行为应类似于您的bash代码,返回所有无错误响应的主机的IP地址:

    $IPAddresses = 100..110 | ForEach-Object { "192.168.0.$_"; }

    $JobList = $IPAddresses | ForEach-Object {
    Test-Connection -ComputerName $_ -Count 1 -AsJob;
    }

    Receive-Job -Job $JobList -AutoRemoveJob -Wait | `
    Where-Object { $_.StatusCode -eq 0 } | `
    Select-Object -ExpandProperty Address;

    在3秒内,针对约250个主机,以上对我而言已完成。
    Test-Connection本身声称最多使用32个同时连接(可通过 -ThrottleLimit设置配置),但是如果您要定位的目标范围很广,则 -Delay选项似乎可以完全覆盖该设置。

    您可能会遇到PowerShell v4及更早版本的问题,因为它的行为可能略有不同。特别是 Test-Connection在Windows或PowerShell的不同版本上似乎是特质的。至少,我一直记得它在以前的版本中抛出错误而不是返回错误状态代码。

    如果您想对ping进行更精细的控制,而不是 Test-Connection给您提供-例如,它默认为1秒超时,因此当任何主机关闭时您要等待的最短时间为1秒-您可能必须恢复为直接调用 Get-WMIObject -Query "SELECT * FROM Win32_PingStatus WHERE Address = '$IP' AND TimeOut = 200" -AsJob

    关于powershell - 使用start子命令为循环改进批处理文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40953234/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com