Присвоить вывод программы переменной с помощью командного файла MS
Мне нужно назначить вывод программы переменной, используя командный файл MS.
Итак, в оболочке GNU Bash я бы использовал VAR=$(application arg0 arg1)
. Мне нужно аналогичное поведение в Windows, используя командный файл.
Что-то вроде set VAR=application arg0 arg1
.
Ответы
Ответ 1
Один из способов:
application arg0 arg1 > temp.txt
set /p VAR=<temp.txt
Другим является:
for /f %%i in ('application arg0 arg1') do set VAR=%%i
Обратите внимание, что первый %
в %%i
используется для выхода из %
после него и необходим при использовании вышеуказанного кода в пакетном файле, а не в командной строке. Представьте, что ваш test.bat
имеет что-то вроде:
for /f %%i in ('c:\cygwin64\bin\date.exe +"%%Y%%m%%d%%H%%M%%S"') do set datetime=%%i
echo %datetime%
Ответ 2
В качестве дополнения к этому предыдущему ответу, трубы могут использоваться внутри оператора for, экранированного символом каретки:
for /f "tokens=*" %%i in ('tasklist ^| grep "explorer"') do set VAR=%%i
Ответ 3
@OP, вы можете использовать для циклов, чтобы отобразить возвращаемый статус вашей программы, если он выводит что-то другое, кроме чисел
Ответ 4
Предполагая, что ваш вывод приложения является числовым кодом возврата, вы можете сделать следующее
application arg0 arg1
set VAR=%errorlevel%
Ответ 5
При выполнении: for /f %%i in ('application arg0 arg1') do set VAR=%%i
я получал ошибку: %% я был неожиданным в это время.
В качестве исправления я должен был выполнить выше как for /f %i in ('application arg0 arg1') do set VAR=%i
Ответ 6
В дополнение к ответу вы не можете напрямую использовать операторы перенаправления вывода в заданной части цикла for
(например, если вы хотите скрыть вывод stderror от пользователя и предоставить более приятное сообщение об ошибке). Вместо этого вы должны избегать их с символом каретки (^
):
for /f %%O in ('some-erroring-command 2^> nul') do (echo %%O)
Ссылка: Перенаправить вывод команды в цикл цикла script
Ответ 7
@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
REM Prefer backtick usage for command output reading:
REM ENABLEDELAYEDEXPANSION is required for actualized
REM outer variables within for scope;
REM within for 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
Ответ 8
это уже было объяснено Охарактеризовано Wolf до
Обратите внимание, что первый% из %% я используется для выхода из% после него и требуется при использовании вышеуказанного кода в пакетном файле, а не в командной строке. Представьте, ваш test.bat имеет что-то вроде:
для/f %% я in ('c:\cygwin64\bin\date.exe + "%% Y %% m %% d %% H %% M %% S" ') установить datetime =% %я echo% datetime%
Ответ 9
Использование труб проще/чище и компактнее.
application arg0 arg1 | set/P output =
Ответ 10
Я написал скрипт, который пингует google.com каждые 5 секунд и регистрирует результаты с текущим временем. Здесь вы можете найти выходные данные для переменных "commandLineStr" (с индексами)
@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
Ответ 11
Вы можете использовать пакетный макрос для простого захвата выходных данных команды, немного похожий на поведение оболочки bash.
Использование макроса просто и выглядит как
%$set% VAR=application arg1 arg2
И это работает даже с трубами
%$set% allDrives="wmic logicaldisk get name /value | findstr "Name""
Макрос использует переменную как массив и сохраняет каждую строку в отдельном индексе.
В образце %$set% allDrives="wmic logicaldisk
будут созданы следующие переменные:
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:
allDrives=<contains the complete text with line feeds>
Чтобы использовать его, не важно понимать, как работает сам макрос.
Полный пример
@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 (0 1 !%~1.max!) 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 LF=^
%=empty=%
)
(set \n=^^^
%=empty=%
)
set $set=FOR /L %%N in (1 1 2) dO IF %%N==2 ( %\n%
setlocal EnableDelayedExpansion %\n%
for /f "tokens=1,* delims== " %%1 in ("!argv!") do ( %\n%
endlocal %\n%
endlocal %\n%
set "%%~1.Len=0" %\n%
set "%%~1=" %\n%
if "!!"=="" ( %\n%
%= Used if delayed expansion is enabled =% %\n%
setlocal DisableDelayedExpansion %\n%
for /F "delims=" %%O in ('"%%~2 | findstr /N ^^"') do ( %\n%
if "!!" NEQ "" ( %\n%
endlocal %\n%
) %\n%
setlocal DisableDelayedExpansion %\n%
set "line=%%O" %\n%
setlocal EnableDelayedExpansion %\n%
set pathExt=: %\n%
set path=; %\n%
set "line=!line:^=^^!" %\n%
set "line=!line:"=q"^""!" %\n%
call set "line=%%line:^!=q""^!%%" %\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%
if %%C == 0 ( %\n%
set "%%~1=%%~L" ! %\n%
) ELSE ( %\n%
set "%%~1=!%%~1!!LF!%%~L" ! %\n%
) %\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 DisableDelayedExpansion^&set argv=
goto :eof