2015-03-19 2 views
0

В основном я пытаюсь читать из текстового файла серверов, свистеть их непрерывно, и выводить метку времени, когда каждый сервер перезагружен (находка «Запрос тайм-аут.»)партии цикла конвейер команды

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

Труба '|' ждет завершения процессов ('ping -t'), прежде чем передать ее следующей команде (' find'); но 'ping -t' не заканчивается ... Я ', боюсь, вам придется строить петлю самостоятельно. – Stephan

+0

Вы пробовали cmd/c?/k сообщает, что окно остается открытым. –

ответ

1

Ваша конструкция не может работать :-(

Ваша первая проблема заключается вы перенаправив вывод команды START, но вы хотите, чтобы трубы вывода PING. Это может быть исправлено путем побега трубы, как ^|.

у вас есть аналогичная проблема с вашей условной командой конкатенации - вам нужно будет ^&^& вместо &&1

Но самая большая проблема вашей ECHO не будет выполняться, пока труба не будет закрыта, которая никогда не НАШЕЛ будет продолжаться.! искать additio nal таймаут после первого. Он не закончится до тех пор, пока труба не будет закрыта, и ваш ECHO не будет работать до тех пор, пока FIND не завершится.

Лучше всего написать скрипт VBScript или JScript или PowerShell для непрерывного пинга сервера и выписать ваше сообщение с отметкой времени при обнаружении таймаута.

Вы можете написать пакетный скрипт, чтобы перебирать список серверов и запускать новый настраиваемый процесс 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, который определяет, ответил ли сервер и записывает сообщение с отметкой времени как на консоль, так и на файл журнала. Файл журнала также используется в качестве файла блокировки для согласованного совместного доступа между процессами.Каждый процесс отслеживает последний статус сервера, и сообщение записывается только при изменении состояния.

@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! 
) 
) 
+0

Вау! Спасибо за этот чрезвычайно тщательный ответ! Интересно, что вы и я решили решить аналогичные методы: –

+0

Спасибо за тщательный ответ! Интересно, что мы прибегали к подобным методам, в отношении пинга -n 1 и перекручивание: "Сервер для проверки перезагрузки" @ECHO OFF набора/р сервера = TITLE Pinging% сервер% с% времени: ~ 0, 5%. : LOOP (ping -n 1% server% | найти «Тайм-аут запроса».> Nul) && (ECHO. & ECHO% сервер% перезагружен в% времени: ~ 0,5%. & GOTO EXIT) || (CLS & Echo Pinging% server% ... & GOTO LOOP) : EXIT ECHO. ECHO Нажмите любую клавишу, чтобы выйти ... ECHO. PAUSE> nul Предоставлено это для особого использования, оно обеспечивает основную функцию. Я буду играть с тем, что вы предоставили, и посмотреть, смогу ли я его адаптировать. Еще раз спасибо! –

+0

EDIT - Исправлена ​​ошибка в первом решении с JREPL - исходный код записывался на консоль после освобождения блокировки (файл закрыт), что было бесполезно. Все исправлено. – dbenham

Смежные вопросы