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
.
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%
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
@OP können Sie für Schleifen verwenden, um den Rückgabestatus Ihres Programms zu erfassen, wenn es etwas anderes als Zahlen ausgibt
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%
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.
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
@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
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
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