基本上我试图从服务器的文本文件中读取,连续ping它们,并在每个服务器重新启动时输出时间戳(查找“请求超时”。)
for /f "delims=" %%a in (Servers_List.txt) do (
start cmd /k ping -t %%a | find "Request timed out."
) && (Echo %%a rebooted at %time%.)
它在一个单独的窗口中启动每个服务器 ping -t
,直到我添加 | find
一块,然后它一次只启动一个在每个后续窗口关闭后。
有没有人知道如何同时运行每个CMD窗口而无需关闭每个先前的窗口?
谢谢!
答案 0 :(得分:1)
您的设计不起作用: - (
你的第一个问题是你正在管道你的START命令的输出,但你想管道输出PING。这可以通过将管道转义为^|
来解决。
条件命令连接遇到类似问题 - 您需要^&^&
而不是&&1
。
但最大的问题是你的ECHO在管道关闭之前不会执行,这绝不是!在检测到第一个超时行后,FIND将继续查找其他超时行。直到管道关闭后它才会结束,并且在FIND终止之后你的ECHO才会运行。
您最好的选择是编写VBScript,JScript或PowerShell脚本以持续ping服务器,并在检测到超时时写出带有时间戳的消息。
您可以编写一个批处理脚本来遍历您的服务器列表,并为每个服务器启动一个新的自定义ping过程。或者您可以将所有内容放入单个VBScript(或JScript或Powershell)脚本中。
也许以下链接之一可以帮助您入门:
http://windowsitpro.com/scripting/how-can-i-use-vbscript-script-ping-machine
http://www.sems.org/2013/07/little-vbscript-to-continously-ping-a-host-with-timestamplog/
https://thwack.solarwinds.com/docs/DOC-135033
我假设您理想地希望在单个屏幕中拥有所有输出。您可以使用START / B选项在同一控制台窗口中运行多个进程,但如果两个进程同时尝试写入控制台,则可能会出现乱码输出的风险。这可以通过进程打开文件进行写入时获得的独占锁来解决。有关如何提供帮助的一些指示,请参阅How do you have shared log files under Windows?。该链接用于共享日志文件,但很容易适用于共享控制台访问。
我已经使用我的JREPL.BAT utility来破解解决方案。在建筑上这是一个令人费解的憎恶,但它的确有效!它为每个服务器运行无限的PING过程,所有这些过程都在同一个控制台中并行执行。每个进程将其输出传递给JREPL,JREPL检测服务器是否响应并向控制台和日志文件写出带时间戳的消息。日志文件还用作锁定文件,以协调进程之间的共享访问。每个进程都会跟踪最后一个服务器状态,并且仅在状态更改时才会写入消息。
@if (@X)==(@Y) @end /* Harmless hybrid line that begins a JScript comment
::***** Batch code *******
@echo off
setlocal enableDelayedExpansion
set "first="
copy nul serverStatus.log >nul
for /f "delims=" %%A in (Servers_List.txt) do if not defined first (
set "first=%%A"
) else (
start /b cmd /c ping -t %%A ^| jrepl "^Request timed out|^Reply from " "log('%%A','DOWN')|log('%%A','UP')" /t "|" /jmatch /jlib "%~f0"
)
if defined first ping -t %first% | jrepl "^Request timed out|^Reply from " "log('%first%','DOWN')|log('%first%','UP')" /t "|" /jmatch /a /jlib "%~f0"
exit /b
****** JScript code ******/
var status = 'initial';
var fso = new ActiveXObject("Scripting.FileSystemObject");
var file;
function log( server, newStatus ) {
if (status!=newStatus) {
status=newStatus;
var msg=new Date().toString()+' '+server+' is '+newStatus;
while (!openFile());
file.WriteLine(msg);
output.WriteLine(msg);
file.Close();
}
return false;
}
function openFile() {
try {
file = fso.OpenTextFile('serverStatus.log',8);
return true;
} catch(e) {
return false;
}
}
但是,我不明白为什么有必要并行运行这些进程。在我看来,你可以简单地进入循环通过服务器的无限循环,并单独PING每个服务器,写出状态。这是一个简单的批处理脚本。同样,它仅在检测到状态变化时才打印出消息。
@echo off
setlocal enableDelayedExpansion
for /l %%N in () do for /f "delims=" %%S in (Servers_List.txt) do (
ping /n 1 %%S | findstr /bc:"Request timed out" >nul && set "status='DOWN'" || SET "status=UP"
if "!status!" neq "!%%S!" (
set "%%S=!status!"
echo !date! !time! %%S is !status!
)
)