【发布时间】:2016-12-03 22:34:10
【问题描述】:
我目前有一个非常简单的脚本,可以 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.bat 来自 192.168.0.101 的回复:字节=32 时间=294ms TTL=64 来自 192.168.0.104 的回复:bytes=32 time=1ms TTL=64
但是,它非常缓慢,而且肯定是按顺序发生的。当我使用 PowerShell Measure-Command 运行它时,我得到了以下结果:
PS C:\Users\derpherp> 测量命令 {start-process test.bat -Wait}
天数:0
小时 : 0
分钟:0
秒数:23
毫秒:107
滴答声:231074173
总天数:0.000267446959490741
总小时数:0.00641872702777778
总分钟数:0.385123621666667
总秒数:23.1074173
总毫秒数:23107.4173
所以我们看到它需要大约 23 秒来执行。
现在,如果我在 Linux 系统上并想做同样的事情,我可以执行以下操作:
#!/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.sh 192.168.0.104 192.168.0.100 192.168.0.103 192.168.0.101
它显示所有阳性结果的时间通常不到一秒,这可以扩展到更大的数字集。
那么,我的问题是,这是批处理脚本的限制吗?我很难相信 bash 在如此简单的任务中的性能比 Windows CMD 解释器好 100 倍?
如果这是有限的,PowerShell 是否提供了一种有竞争力的方式来创建任务?我在 foreach 循环中使用了Start-Job,但对于大量任务(即 /16 网络上的 Test-Connection)似乎变得不可行
编辑 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 的唯一窗口,并且需要同样长的时间才能完成。
【问题讨论】:
-
在您的场景中 bash 优于 CMD 的原因是您的 bash 脚本在后台运行进程,因此它们不是按顺序运行而是并行运行。 CMD 并不真正支持这一点。要在 CMD 中执行类似的操作,您必须在新的 CMD 实例中启动每个
ping,这不允许您在单个窗口中获取输出。
标签: windows powershell batch-file cmd parallel-processing