windows - BATCH - Gem kommandoudgang til variabel

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg vil gerne lave et flagermusskript, der kun udfører en handling, hvis færre end 2 forekomster af cmd.exe kører. Det lykkedes mig at finde en løsning, der lagrer forekomststællingen i en midlertidig fil, men jeg finder det meget uendeligt. Så mit spørgsmål er, hvordan man gør det samme som nedenfor uden en midlertidig fil, men snarere ved at gemme forekomsttællingen givet af @TASKLIST | FIND /I /C "\%\_process\%" i en variabel. Jeg så, at der kan være en løsning med en for loop, men jeg kunne ikke få det til at arbejde, og alligevel ville jeg virkelig foretrække en løsning baseret på SET (hvis dette er muligt).


@SET \_process=cmd.exe
@SET \_temp\_file=tempfiletodelete.txt
@TASKLIST | FIND /I /C "\%\_process\%" > \%\_temp\_file\%
@SET /p \_count=<\%\_temp\_file\%
@DEL /f \%\_temp\_file\%
@IF \%\_count\% LSS 2 (
    @ECHO action 1
) ELSE (
    @ECHO action 2
)


 Dette spørgsmål svarer til Gem output fra FIND-kommando til variabel, men jeg kunne ikke anvende løsningen på mit problem, og jeg ønskede at vide, om en løsning uden en for-loop er mulig.

Bedste reference


Kommandoen FOR med valgmulighed /F og kommandoen eller kommandolinjen angivet som sæt (streng inden parentes) derudover er vedlagt af ' kan bruges til behandler output fra en kommando eller en kommandolinje med flere kommandoer på en linje.


Du kan bruge denne batchfil:


@ECHO OFF
SET "\_process=cmd.exe"
FOR /F \%\%I IN ('\%SystemRoot\%System32	asklist.exe /FI "IMAGENAME eq \%\_process\%" ^| \%SystemRoot\%System32find.exe /I /C "\%\_process\%"') DO SET "\_count=\%\%I"
IF /I "\%\_process\%" == "cmd.exe" SET /A \_count-=1
IF \%\_count\% LSS 2 (
    ECHO action 1
) ELSE (
    ECHO action 2
)


Kommandoen FOR kører i baggrunden uden et synligt konsolvindue cmd.exe /C med kommandolinjen:


C:WindowsSystem32	asklist.exe /FI "IMAGENAME eq cmd.exe" | C:WindowsSystem32find.exe /I /C "cmd.exe"


TASKLIST indstilling /FI "IMAGENAME eq cmd.exe" filtrerer output fra TASKLIST allerede til processer med billednavn (= navn på eksekverbar) cmd.exe. Dette gør yderligere behandling hurtigere og undgår, at en køreproces med filnavn totalcmd.exe tælles som cmd.exe som den pågældende kommandolinje gør.


Udgangen af ​​ TASKLIST skrevet til at håndtere STDOUT omdirigeres til at håndtere STDIN kommando FIND , der behandler linjerne og tæller linjerne indeholder cmd.exe hvor som helst i køen. FIND output slutter antallet af linjer, der indeholder søgt streng for at håndtere STDOUT af kommandoprocessen, der kører i baggrunden.


Omdirigeringsoperatøren | skal undslippes med karet karakter ^ FOR kommandolinjen, der skal fortolkes som bogstavkarakter, når Windows-kommandolyderen behandler denne kommandolinje, før kommandoen FOR , som udfører den indlejrede kommandolinje i en separat kommandoproces, der startes i baggrunden.


FOR med mulighed /F fanger alt skrevet til at håndtere STDOUT af udført kommandoproces og behandler hver linje. I dette tilfælde er der kun en linje fanget af FOR , der kun indeholder et nummer. Derfor er der ikke behov for yderligere muligheder for at tildele nummeret til sløjfevariabel I ved FOR til miljøvariabel \_count ved hjælp af kommandoen SET .


Målet med denne batchfil tæller antallet af cmd.exe processer, der allerede kører. Da kommandolinjen med TASKLIST og FIND udføres af FOR i baggrunden med en yderligere cmd.exe -proces, er det nødvendigt at subtrahere tællingen med en for at få det rigtige resultat ved hjælp af et aritmetisk udtryk evalueret med SET /A \_count-=1. Denne nedskrivning med én er kun nødvendig for at tælle rigtigt antallet af cmd.exe processer. Det er ikke nødvendigt for nogen anden proces.


For at forstå de anvendte kommandoer og hvordan de virker, skal du åbne et kommandopromptvindue, udføre de følgende kommandoer, og læs helt alle hjælpesider, der vises for hver kommando, meget omhyggeligt.



  • echo /?

  • find /?

  • for /?

  • if /?

  • set /?

  • tasklist /?


Andre referencer 1


Du ville gøre det sådan, ved at bruge TaskList i en For loop:


@Set "\_process=cmd.exe"
@For /F \%\%A In ('TaskList^|Find /C /I "\%\_process\%"'
) Do @If \%\%A Lss 2 (Echo Action 1) Else Echo Action 2
@Pause


Du kan også udføre en lignende ting ved hjælp af WMIC også:


@Set "\_process=cmd.exe"
@For /F \%\%A In ('WMIC Process Get Name^|Find /C "\%\_process\%"'
) Do @If \%\%A Lss 2 (Echo Action 1) Else Echo Action 2
@Pause


Disse kan blive raffineret yderligere for at sikre processer, der indeholder strengen i modsætning til at matche det, der ikke tælles:


@Set "\_process=cmd.exe"
@For /F \%\%A In ('TaskList /FI "ImageName Eq "\%\_Process\%""^|Find /C "."'
) Do @If \%\%A Lss 2 (Echo Action 1) Else Echo Action 2
@Pause





@Set "\_process=cmd.exe"
@For /F \%\%A In (
    'WMIC Process Where "Name='\%\_process\%'" Get Name^|Find /C "."'
) Do @If \%\%A Lss 2 (Echo Action 1) Else Echo Action 2
@Pause


Bemærk :
Hvis du virkelig kontrollerer processen cmd.exe, skal du være opmærksom på, at en kommando inde i For loop parenteserne er opstået i en ny cmd.exe]] eksempel (derved øges dit antal med 1)