I've currently got a very simple script which pings 10 IPs:
@ECHO OFF
for /L %%i in (100, 1, 110) DO (
START /W /B cmd /c ping -n 1 192.168.0.%%i | find "time="
)
The output is as expected:
C:\Users\herpderp>test.bat Reply from 192.168.0.101: bytes=32 time=294ms TTL=64 Reply 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 : 0 Hours : 0 Minutes : 0 Seconds : 23 Milliseconds : 107 Ticks : 231074173 TotalDays : 0.000267446959490741 TotalHours : 0.00641872702777778 TotalMinutes : 0.385123621666667 TotalSeconds : 23.1074173 TotalMilliseconds : 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
The result is different in a variety of ways:
The results aren't always sequential, meaning it actually started the commands more asynchronously:
root@kali:~/vids/bash_scripting# ./test.sh 192.168.0.104 192.168.0.100 192.168.0.103 192.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="
)
This outputs the current window and takes just as long as the initial variant
@ECHO OFF
for /L %%i in (100, 1, 110) DO (
START ping -n 1 192.168.0.%%i | find "time="
)
This outputs to unique windows per IP and takes just as long to complete.