it-swarm.com.de

Weisen Sie die Ausgabe eines Programms mithilfe einer MS-Stapeldatei einer Variablen zu

Ich muss die Ausgabe eines Programms mithilfe einer MS-Batchdatei einer Variablen zuweisen.

In GNU Bash Shell würde ich VAR=$(application arg0 arg1) verwenden. Ich brauche ein ähnliches Verhalten in Windows mit einer Batchdatei.

So etwas wie set VAR=application arg0 arg1.

230
initialZero

Ein Weg ist:

application arg0 arg1 > temp.txt
set /p VAR=<temp.txt

Ein anderes ist:

for /f %%i in ('application arg0 arg1') do set VAR=%%i

Beachten Sie, dass der erste % in %%i verwendet wird, um den % nach dem Escape zu umgehen, und ist erforderlich, wenn Sie den obigen Code in einer Batchdatei und nicht in der Befehlszeile verwenden. Stellen Sie sich vor, Ihr test.bat hat etwas wie:

for /f %%i in ('c:\cygwin64\bin\date.exe +"%%Y%%m%%d%%H%%M%%S"') do set datetime=%%i
echo %datetime%
353

Als Ergänzung zu dieser vorherigen Antwort können Pipes innerhalb einer for -Anweisung verwendet werden, die durch ein Caret-Symbol geschützt wird:

    for /f "tokens=*" %%i in ('tasklist ^| grep "Explorer"') do set VAR=%%i
57
Renat

@OP können Sie für Schleifen verwenden, um den Rückgabestatus Ihres Programms zu erfassen, wenn es etwas anderes als Zahlen ausgibt

8
ghostdog74

wenn Sie davon ausgehen, dass die Ausgabe Ihrer Anwendung ein numerischer Rückkehrcode ist, können Sie Folgendes tun

application arg0 arg1
set VAR=%errorlevel%
6
akf

Beim Ausführen von: for /f %%i in ('application arg0 arg1') do set VAR=%%i wurde ein Fehler angezeigt: %% Ich war zu diesem Zeitpunkt unerwartet. Als Fix musste ich oben als for /f %i in ('application arg0 arg1') do set VAR=%i ausführen.

5
Munish Mehta

Zusätzlich zur Antwort können Sie die Umleitungsoperatoren für die Ausgabe nicht direkt im set - Teil der for-Schleife verwenden (z. B., wenn Sie die Stderror-Ausgabe eines Benutzers ausblenden und eine schönere Fehlermeldung anzeigen möchten). Stattdessen müssen Sie sie mit einem Caret-Zeichen (^) versehen:

for /f %%O in ('some-erroring-command 2^> nul') do (echo %%O)

Referenz: Ausgabe des Befehls in der Schleife des Batch-Skripts umleiten

1
Kubo2
@echo off
SETLOCAL ENABLEDELAYEDEXPANSION

REM Prefer backtick usage for command output reading:
REM ENABLEDELAYEDEXPANSION is required for actualized
REM  outer variables within for's scope;
REM within for's scope, access to modified 
REM outer variable is done via !...! syntax.

SET CHP=C:\Windows\System32\chcp.com

FOR /F "usebackq tokens=1,2,3" %%i IN (`%CHP%`) DO (
    IF "%%i" == "Aktive" IF "%%j" == "Codepage:" (
        SET SELCP=%%k
        SET SELCP=!SELCP:~0,-1!
    )
)
echo actual codepage [%SELCP%]

ENDLOCAL
0
rcm

Sie können ein Batch-Makro zum einfachen Erfassen von Befehlsausgaben verwenden, ähnlich wie das Verhalten der Bash-Shell. 

Die Verwendung des Makros ist einfach und sieht so aus

%$set% VAR=application arg1 arg2

Und es funktioniert auch mit Rohren

%$set% allDrives="wmic logicaldisk get name /value | findstr "Name""

Das Makro verwendet die Variable wie ein Array und speichert jede Zeile in einem separaten Index.
Im Beispiel von %$set% allDrives="wmic logicaldisk werden die folgenden Variablen erstellt: 

allDrives.Len=5
allDrives.Max=4
allDrives[0]=Name=C:
allDrives[1]=Name=D:
allDrives[2]=Name=F:
allDrives[3]=Name=G:
allDrives[4]=Name=Z:

Um es zu benutzen, ist es nicht wichtig zu verstehen, wie das Makro selbst funktioniert.

Das vollständige Beispiel

@echo off
setlocal

call :initMacro

%$set% ipOutput="ipconfig"
call :ShowVariable ipOutput
echo First line is %ipOutput[0]%

echo( 
%$set% driveNames="wmic logicaldisk get name /value | findstr "Name""
call :ShowVariable driveNames

exit /b

:ShowVariable
setlocal EnableDelayedExpansion
for /L %%n in (1 1 !%~1.len!) do (
    echo %%n: !%~1[%%n]!
)
echo(
exit /b

:initMacro
if "!!"=="" (
    echo ERROR: Delayed Expansion must be disabled while defining macros
    (goto) 2>nul
    (goto) 2>nul
)
(set \n=^^^
%=empty=%
)

set $set=FOR /L %%N in (1 1 2) DO IF %%N==2 ( %\n%
    for /f "tokens=1,* delims== " %%1 in ("!argv!") do (            %\n%
        endlocal                                                    %\n%
        endlocal                                                    %\n%
        set "%%~1.Len=0"                                            %\n%
        if "!!"=="" (                                               %\n%
            %= Used if delayed expansion is enabled =%              %\n%
            for /F "delims=" %%O in ('"%%~2 | findstr /N ^^"') do ( %\n%
                setlocal DisableDelayedExpansion                    %\n%
                set pathExt=:                                       %\n%
                set "line=%%O"                                      %\n%
                call set ^"line=%%line:"="Q"%%"                     %\n%
                call set "line=%%line:!="B"!%%"                     %\n%
                setlocal EnableDelayedExpansion                     %\n%
                set "line=!line:^=^^!"                              %\n%
                set "line=!line:"B"=^!"                             %\n%
                set "line=!line:"Q"=^"!^"                           %\n%
                set "line="!line:*:=!""                             %\n%
                for /F %%C in ("!%%~1.Len!") DO (                   %\n%
                    FOR /F "delims=" %%L in ("!line!") DO (         %\n%
                        endlocal                                    %\n%
                        endlocal                                    %\n%
                        set "%%~1[%%C]=%%~L" !                      %\n%
                    )                                               %\n%
                    set /a %%~1.Len+=1                              %\n%
                )                                                   %\n%
            )                                                       %\n%
        ) ELSE (                                                    %\n%
            %= Used if delayed expansion is disabled =%             %\n%
            for /F "delims=" %%O in ('"%%~2 | findstr /N ^^"') do ( %\n%
                setlocal DisableDelayedExpansion                    %\n%
                set "line=%%O"                                      %\n%
                setlocal EnableDelayedExpansion                     %\n%
                set "line="!line:*:=!""                             %\n%
                for /F %%C in ("!%%~1.Len!") DO (                   %\n%
                    FOR /F "delims=" %%L in ("!line!") DO (         %\n%
                        endlocal                                    %\n%
                        endlocal                                    %\n%
                        set "%%~1[%%C]=%%~L"                        %\n%
                    )                                               %\n%
                    set /a %%~1.Len+=1                              %\n%
                )                                                   %\n%
            )                                                       %\n%
        )                                                           %\n%
        set /a %%~1.Max=%%~1.Len-1                                  %\n%
        )                                                           %\n%
    ) else setlocal EnableDelayedExpansion^&setlocal^&set argv=

goto :eof
0
jeb

Ich schrieb das Skript, das google.com alle 5 Sekunden pingt und die Ergebnisse mit der aktuellen Uhrzeit protokolliert. Hier finden Sie die Ausgabe der Variablen "commandLineStr" (mit Indizes).

@echo off

:LOOPSTART

echo %DATE:~0% %TIME:~0,8% >> Pingtest.log

SETLOCAL ENABLEDELAYEDEXPANSION
SET scriptCount=1
FOR /F "tokens=* USEBACKQ" %%F IN (`ping google.com -n 1`) DO (
  SET commandLineStr!scriptCount!=%%F
  SET /a scriptCount=!scriptCount!+1
)
@ECHO %commandLineStr1% >> PingTest.log
@ECHO %commandLineStr2% >> PingTest.log
ENDLOCAL

timeout 5 > nul

GOTO LOOPSTART
0
Ja Vy