Boruyu Windows toplu iş dosyasında bir değişkene yönlendir


5

Bir toplu iş dosyasında Windows komut satırını kullanarak uzaktaki bir bilgisayardan bir Windows hizmetini durdurmak ve başlatmak istiyorum.

sc \\192.168.1.1 stop <ServiceName>

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

Ancak, hizmetin durduğundan veya başlatıldığından emin olana kadar beklemek istiyorum. Bu yüzden, durum DURDURULMADIĞINDAN duruma kadar sürekli döngü yapıp durumu kontrol etmeyi planlıyordum.

Sunucuya tekrarlanan isteğin işlemcinin yoğun olabileceğini düşünüyorum ancak kontrol zamanındaki bazı saldırılar dışında komut satırını beklemek yok. Ancak benim asıl sorum, Windows hizmetinin durumunu nasıl alırım, böylece bir sonraki komuta devam etmem uygunsa, bir IF deyimi ile kontrol edebilir miyim?

Yanıtlar:


7

Bir komutun çıktısına bir değişken ayarlamak için, for /f:

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

Sorun, komutta bir boru kullanmak için komut satırı kaçış karakteriyle kaçmanız gerekir: ^, bu nedenle: ^|.

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

Şimdi, hangi Windows sürümünü kullandığınızdan emin değilim, ancak sc Windows 7'de sorgu aşağıdaki çıktıyı verir:

>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

Bu bir demektir findstr STATE çıktısını veren gerekli olacaktır:

>sc query SamSs | findstr STATE
        STATE              : 4  RUNNING

Şimdi, yukarıdaki örnekte, tokens=* her token değişkene ayarlandığı anlamına gelir %%abelirteçlerin boşluklarla ayrıldığı yer. Bu durumda, üçüncü simgeyi kullanabilirsiniz ( 4 ) veya dördüncü simge ( RUNNING ). Bu arada, testlerle, 1 karşılık gelir STOPPED benim için.

İşleri kolaylaştırmak için dizeyi kullanacağım RUNNING bu örnekte. Dördüncü belirteci istiyoruz.

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

Tabii ki, neye bağlı olarak sc query çıktılar, sizinki biraz farklı olabilir, o yüzden oraya nasıl geldiğimi izleyin ve gerektiğinde değiştirin. Veya bir yorumda çıktınızın çıktısını alın. sc query ve gerektiği gibi değiştireceğim.

Değeri kontrol etmek için şunları kullanabilirsiniz:

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

Senin durumunda, döngü böyle bir şey giderdi.

: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

Bunu not et timeout yalnızca Windows Vista ve sonraki sürümlerinde bulunan bir yardımcı programdır. Windows XP kullanabilir gibi bir şey ping 1.1.1.1 -n 1 -w 5000 > nul.


Teşekkürler Bob, Çok detaylıydı. Ama sanırım kodumda eksik olan minik bit, şapka karakterini kullanan kaçan boru idi. Ancak bu gelecekteki referans için yardımcı olacaktır. :)
Nassign

1

Daha yüksek karmaşıklık seviyesine sahip daha gelişmiş bir örnek

(aynı zamanda daha yüksek kullanılabilirlik)

  • birkaç ortak uygulama kullanarak ( cURL, GREP, SED ) Bunların bir Win32 pre-build versiyonunu indirebilir veya kullanabilirsiniz cygwin 'deki exe dosyaları- her ikisi de mükemmel çalışıyor (cygwin için, sadece koymak daha iyi c:\cygwin\bin\ sisteminizin klasör konumu PATH kolay erişim için değişken).
  • BORU işleme (STDOUT ve STDERR aracılığıyla işlenir).
  • kaçan semboller ( |, >, & ) - Windows 7'de en iyi uygulama / gerekli.
  • döngü yok , hayır
  • sayısal verilerle çalışma ( curl yanıt başlığı Content-Length )
  • Ve.. Geçici dosya yok!


@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

çıkacak it is 41MB

(orijinal başlık Content-Length: 43597312 )


buradan aldı:  - CMD / Bash Script Ninja - cURL Yanıt Başlığı Numarası Manipülasyon


0

Kontrol etmek isteyebilirsiniz PsTools Microsoft tarafından (Sysinternals). Denilen bir araç var PsService Parametreleri kullanarak servisleri uzaktan kontrol edebilirsiniz. \\computer


-2

"yyy" yı "yyy = 1 toto" a nasıl ayarlayabileceğimizi bilmek sadece bir örnek ilk une () çıkış "yyy = 1 toto", ancak "Ortam değişkeni yyy tanımlanmadı" deyince satır sonlandırıldı.

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

1
Bunun soruyu nasıl cevapladığını anlamıyorum. Farklı bir soruya cevap veriyor gibi görünüyorsun.
Chenmunka

üzgünüm ingilizce loll iyi değilim ... ne zaman: echo toto tata titi | awk.exe -F "tata" "{baskı NR, $ 1}" | (set / p yyy = & yyy set) satır yazdırma sonunda yyy: yyy = 1 ikinci satırdaki yyy ayarına yyy: ortam değişkeni yyy tanımlanmadı Kodun ilk satırını ikincil satır yazdırma yyy için ayarla: yyy = 1 toto
Risoos
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.