Redirecionar o canal para uma variável no arquivo em lotes do Windows

3

Eu quero parar e iniciar um serviço do Windows a partir de um PC remoto usando a linha de comando do Windows, em um arquivo de lote.

sc \192.168.1.1 stop <ServiceName>

rem sc \192.168.1.1 query <ServiceName> | findstr STATUS | SET VAR=

No entanto, desejo aguardar até que o status do serviço seja interrompido ou iniciado. Então, eu estava planejando fazer um loop e verificar o status continuamente até que o status seja STOPPED.

Acho que a solicitação repetida para o servidor pode exigir muito do processador, mas não há espera pela linha de comando, exceto por alguns hacks no tempo de verificação. Mas a minha principal questão é como obtenho o status do serviço do Windows para que eu possa verificar com uma instrução IF se estiver OK para prosseguir para o próximo comando?

    
por Nassign 26.03.2012 / 03:55

4 respostas

6

Para definir uma variável para a saída de um comando, use for /f :

for /f "tokens=*" %%a in ('command') do set _CmdResult=%%a

O problema é que, para usar um pipe no comando, você precisa escapar com o caractere de escape da linha de comando: ^ , portanto: ^| .

for /f "tokens=*" %%a in ('sc \192.168.1.1 query <ServiceName> ^| findstr STATUS') do set _CmdResult=%%a

Agora, não sei qual versão do Windows você está executando, mas minhas tentativas em uma consulta sc no Windows 7 fornecem a seguinte saída:

>sc query SamSs
SERVICE_NAME: SamSs
        TYPE               : 20  WIN32_SHARE_PROCESS
        STATE              : 4  RUNNING
                                (NOT_STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0

Isso significa que findstr STATE seria necessário, o que dá a saída:

>sc query SamSs | findstr STATE
        STATE              : 4  RUNNING

Agora, no exemplo acima, tokens=* significa que cada token é definido para a variável %%a , em que os tokens são separados por espaços. Nesse caso, você pode usar o terceiro token ( 4 ) ou o quarto token ( RUNNING ). By the way, com o teste, 1 corresponde a STOPPED para mim.

Para facilitar as coisas, usarei a string RUNNING neste exemplo. Então, queremos o quarto token.

for /f "tokens=4" %%a in ('sc \192.168.1.1 query <ServiceName> ^| findstr STATE') do set _CmdResult=%%a

É claro que, dependendo do seu sc query , o seu pode ser um pouco diferente, então siga como eu cheguei lá e modifique conforme necessário. Ou poste em um comentário a saída do seu sc query e modificarei conforme necessário.

Para verificar o valor, você pode usar:

if %_CmdResult%==STOPPED (
    REM do something here
)

No seu caso, o loop seria algo assim.

:loop
for /f "tokens=*" %%a in ('sc \192.168.1.1 query <ServiceName> ^| findstr STATUS') do set _CmdResult=%%a
if %_CmdResult%==STOPPED (
    sc \192.168.1.1 start <ServiceName>
    goto endloop
)
timeout /t 5
goto loop
:endloop

Observe que timeout é um utilitário incluído apenas no Windows Vista e posterior. O Windows XP pode usar algo como ping 1.1.1.1 -n 1 -w 5000 > nul .

    
por 28.03.2012 / 10:41
1

Um exemplo mais avançado com nível de complexidade mais alto

(mas também maior usabilidade)

  • usando vários aplicativos comuns ( cURL , GREP , SED ) você pode fazer download de versões pré-compiladas do Win32 ou usar arquivos exe do cygwin Windows- ambos funcionam perfeitamente bem (para o cygwin, é melhor colocar c:\cygwin\bin\ localização da pasta na variável PATH do seu sistema para facilitar o acesso).
  • Processamento de PIPE (STDOUT e STDERR são processados).
  • símbolos de escape ( | , > , & ) - prática recomendada / necessária no Windows7 +.
  • sem loops , não goto
  • trabalhando com dados numéricos ( curl cabeçalho de resposta Content-Length )
  • E .. SEM ARQUIVOS TEMPORÁRIOS!

@echo off

setlocal enableextensions
  for /f "tokens=*" %%a in ('curl --head --ipv4 --sslv3 --silent --location-trusted --url "https://storage.googleapis.com/chromium-browser-continuous/Win_x64/362418/mini_installer.exe" 2^>^&1 ^| grep "Content-Length" 2^>^&1 ^| sed "s/\r\n$//g" 2^>^&1 ^| sed "s/content-length\:\ //gi" 2^>^&1') do ( set /a num=%%a )

  set /a num=%num% / 1024 / 1024

  echo it is %num%MB
endlocal

produzirá it is 41MB

(o cabeçalho original é Content-Length: 43597312 )

levou daqui:  - Manipulação de Números de Cabeçalhos de Resposta CMD / Bash - Manipulação de Números de Cabeçalho de Resposta cURL

    
por 02.12.2015 / 01:30
0

Você pode verificar o PsTools da Microsoft (Sysinternals). Existe uma ferramenta chamada PsService , onde você pode verificar remotamente os serviços através do parâmetro \computer

    
por 28.03.2012 / 10:31
-1

é apenas um exemplo para saber como pode "definir yyy" para fora "yyy = 1 toto" o primeiro une () out "yyy = 1 toto" mas a linha juste depois diz "Variável de ambiente yyy não definida"

echo toto tata titi|awk.exe -F"tata" "{print NR,$1}"|(set /p yyy=&set yyy)
set yyy
    
por 29.08.2017 / 12:12