Pregunta

Necesito asignar la salida de un programa a una variable con un archivo por lotes de MS.

Así que en GNU Bash me gustaría utilizar VAR=$(application arg0 arg1). Necesito un comportamiento similar en Windows utilizando un archivo por lotes.

Algo así como set VAR=application arg0 arg1.

¿Fue útil?

Solución

Una forma es:

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

Otra es:

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

Tenga en cuenta que la primera % en %%i se utiliza para escapar de la % después y se necesita cuando se utiliza el código anterior en un archivo por lotes en lugar de en la línea de comandos. Imagínese, su test.bat tiene algo como:

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

Otros consejos

Como una adición a esta respuesta anterior , tubos pueden ser utilizados en el interior de un comunicado, se escaparon por un acento circunflejo:

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

@OP, puede utilizar para bucles para capturar el estado de retorno de su programa, si da salida a algo distinto de los números

suponiendo que la salida de su aplicación es un código de retorno numérico, puede hacer lo siguiente

application arg0 arg1
set VAR=%errorlevel%

Al ejecutar: for /f %%i in ('application arg0 arg1') do set VAR=%%i que estaba haciendo de error: %% i fue inesperado en este momento. Como una solución, que tenía que ejecutar anteriormente como for /f %i in ('application arg0 arg1') do set VAR=%i

Además de la respuesta, no se puede utilizar directamente operadores de redirección de salida en el Set parte de bucle for (por ejemplo, si quieres ocultar la salida estándar de error de un usuario y proporciona un mensaje de error más agradable) . En su lugar, usted tiene que escapar de ellos con un carácter de intercalación (^):

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

Referencia: redirigir la salida de mando en bucle de escritura de la hornada

Se podría utilizar una macro sencilla lotes para la captura de las salidas de comando, un poco como el comportamiento de la cáscara del golpe.

El uso de la macro es simple y se parece a

%$set% VAR=application arg1 arg2

Además, funciona incluso con tuberías

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

Los usos macro la variable como una matriz y tiendas de cada línea en un índice separado.
En la muestra de %$set% allDrives="wmic logicaldisk habrá creado las siguientes variables:

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>

Para usarlo, no es importante entender cómo funciona la macro en sí.

El ejemplo completo

@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
@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

Me escribió el guión que hace ping google.com cada 5 segundos y los resultados de explotación forestal con la hora actual. Aquí puede encontrar la salida a las variables "commandLineStr" (con índices)

@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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top