Câu trả lời:
Một cách là:
application arg0 arg1 > temp.txt
set /p VAR=<temp.txt
Cái khác là:
for /f %%i in ('application arg0 arg1') do set VAR=%%i
Lưu ý rằng người đầu tiên %
trong %%i
được sử dụng để thoát khỏi %
sau khi nó và là cần thiết khi sử dụng các mã trên trong một tập tin thực thi chứ không phải trên dòng lệnh. Hãy tưởng tượng, bạn test.bat
có một cái gì đó như:
for /f %%i in ('c:\cygwin64\bin\date.exe +"%%Y%%m%%d%%H%%M%%S"') do set datetime=%%i
echo %datetime%
for /f "tokens=3" %%i in ('route print ^| findstr "\<0.0.0.0\>"') do set "myVar=%%i"
Ngoài ra, trong câu trả lời trước đó , các đường ống có thể được sử dụng trong câu lệnh for, được thoát bằng biểu tượng dấu mũ:
for /f "tokens=*" %%i in ('tasklist ^| grep "explorer"') do set VAR=%%i
for /f "tokens=*" %i in ('tasklist ^| findstr explorer') do @echo %i
Nhưng nói chung, usebackq
nên được sử dụng để xử lý các lệnh phức tạp.
for /f "tokens=*" %%i in ('"tasklist | grep explorer"') do set VAR=%%i
. Dễ dàng hơn cho tôi nếu không có dấu ngoặc kép trong lệnh.
@OP, bạn có thể sử dụng các vòng lặp để nắm bắt trạng thái trả về của chương trình, nếu nó xuất ra thứ gì đó không phải là số
giả sử rằng đầu ra của ứng dụng của bạn là mã trả về số, bạn có thể làm như sau
application arg0 arg1
set VAR=%errorlevel%
Khi thực hiện: for /f %%i in ('application arg0 arg1') do set VAR=%%i
tôi đã gặp lỗi: %% tôi không ngờ vào lúc này. Để khắc phục, tôi đã phải thực hiện ở trên nhưfor /f %i in ('application arg0 arg1') do set VAR=%i
%%
và bên ngoài một tệp bó trên một dòng lệnh bạn cần%
Ngoài câu trả lời, bạn không thể trực tiếp sử dụng các toán tử chuyển hướng đầu ra trong phần thiết lập của for
vòng lặp (ví dụ: nếu bạn muốn ẩn đầu ra stderror khỏi người dùng và cung cấp thông báo lỗi đẹp hơn). Thay vào đó, bạn phải thoát chúng bằng ký tự dấu mũ ( ^
):
for /f %%O in ('some-erroring-command 2^> nul') do (echo %%O)
Tham khảo: Chuyển hướng đầu ra của lệnh trong vòng lặp của tập lệnh bó
@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
Bạn có thể sử dụng một macro bó để chụp các đầu ra lệnh đơn giản, giống như hành vi của bash shell.
Việc sử dụng macro rất đơn giản và trông giống như
%$set% VAR=application arg1 arg2
Và nó hoạt động ngay cả với đường ống
%$set% allDrives="wmic logicaldisk get name /value | findstr "Name""
Macro sử dụng biến như một mảng và lưu trữ mỗi dòng trong một chỉ mục riêng biệt.
Trong mẫu của %$set% allDrives="wmic logicaldisk
các biến sau sẽ được tạo:
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>
Để sử dụng nó, không quan trọng để hiểu cách thức hoạt động của macro.
Ví dụ đầy đủ
@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
Tôi đã viết kịch bản ping google.com cứ sau 5 giây và ghi lại kết quả với thời gian hiện tại. Tại đây bạn có thể tìm đầu ra cho các biến "lệnhLineStr" (có chỉ số)
@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