Pregunta ¿Cómo paso los parámetros de la línea de comando a un archivo por lotes?


Necesito pasar el id y la contraseña a un archivo cmd (o bat) en el momento de ejecutar en lugar de codificarlos en el archivo.

Así es como se ve la línea de comando:

test.cmd admin P@55w0rd > test-log.txt

904
2017-08-25 18:14


origen


Respuestas:


Otro consejo útil es usar %* para significar "todos". Por ejemplo:

echo off
set arg1=%1
set arg2=%2
shift
shift
fake-command /u %arg1% /p %arg2% %*

Cuando corres:

test-command admin password foo bar

el archivo por lotes anterior se ejecutará:

fake-command /u admin /p password foo bar

Puedo tener la sintaxis ligeramente incorrecta, pero esta es la idea general.


805
2017-08-25 19:41



Así es como lo hago.

@fake-command /u %1 /p %2

Así es como se ve la línea de comando:

test.cmd admin P@55w0rd > test-log.txt

El% 1 se aplica al primer parámetro, el% 2 (y aquí está la parte engañosa) se aplica al segundo. Puede tener hasta 9 parámetros pasados ​​de esta manera.


225
2017-09-18 12:26



Si desea manejar de forma inteligente los parámetros que faltan, puede hacer algo como:

IF %1.==. GOTO No1
IF %2.==. GOTO No2
... do stuff...
GOTO End1

:No1
  ECHO No param 1
GOTO End1
:No2
  ECHO No param 2
GOTO End1

:End1

117
2017-08-25 20:03



Acceder a los parámetros del lote puede ser simple con% 1,% 2, ...% 9 o también% *,
pero solo si el contenido es simple.

No hay una manera simple para contenidos complejos como "&"^&, ya que no es posible acceder a% 1 sin producir un error.

set  var=%1
set "var=%1"
set  var=%~1
set "var=%~1"

Las líneas se expanden a

set  var="&"&
set "var="&"&"
set  var="&"&
set "var="&"&"

Y cada línea falla, como una de las & está fuera de las cotizaciones.

Se puede resolver leyendo un archivo temporal a comentó versión del parámetro.

@echo off
SETLOCAL DisableDelayedExpansion

SETLOCAL
for %%a in (1) do (
    set "prompt="
    echo on
    for %%b in (1) do rem * #%1#
    @echo off
) > param.txt
ENDLOCAL

for /F "delims=" %%L in (param.txt) do (
  set "param1=%%L"
)
SETLOCAL EnableDelayedExpansion
set "param1=!param1:*#=!"
set "param1=!param1:~0,-2!"
echo %%1 is '!param1!'

El truco es habilitar echo on y expanda el% 1 después de una rem declaración (también funciona con% 2 ..% *).
Aun asi "&"& podría repetirse sin producir un error, como se comenta.

Pero para poder redirigir la salida de la echo on, necesitas los dos FOR-LOOPS.

Los personajes extra * # se usan para protegerse contra contenidos como /? (mostraría la ayuda para REM).
O una referencia en el extremo de la línea podría funcionar como un carácter multilínea, incluso después de una rem.

Luego leyendo el parámetro rem salida del archivo, pero con cuidado.
El FOR / F debería funcionar con la expansión diferida desactivada, de lo contrario el contenido con "!" sería destruido
Después de eliminar los caracteres adicionales en param1, lo tienes.

Y para usar param1 de forma segura, habilite la expansión retrasada.


71
2018-03-30 22:16



Sí, y no olvides usar variables como %%1 cuando usas if y for y la pandilla

Si olvidas el doble %, entonces sustituirá en argumentos de línea de comando (posiblemente nulos) y recibirá algunos mensajes de error bastante confusos.


51
2017-08-25 18:16



No hay necesidad de complicarlo. Es simplemente comandos% 1% 2 parámetros, por ejemplo,

@echo off

xcopy %1 %2 /D /E /C /Q /H /R /K /Y /Z

echo copied %1 to %2

pause

La "pausa" muestra lo que ha hecho el archivo por lotes y espera a que presione la tecla ANY. Guárdelo como xx.bat en la carpeta de Windows.

Para usarlo, escriba, por ejemplo:

xx c:\f\30\*.* f:\sites\30

Este archivo por lotes se ocupa de todos los parámetros necesarios, como copiar solo archivos, que son más nuevos, etc. Lo he usado desde antes de Windows. Si le gusta ver los nombres de los archivos, ya que se están copiando, omita el Q parámetro.


45
2018-04-18 23:46



@ECHO OFF
:Loop
IF "%1"=="" GOTO Continue
SHIFT
GOTO Loop
:Continue

Nota: SI "%1"=="" causará problemas si %1 está encerrado entre comillas.

En ese caso, use IF [%1]==[]o, en NT 4 (SP6) y posterior solamente, IF "%~1"=="" en lugar.


30
2018-03-14 06:02



Recientemente, un amigo me preguntó sobre este tema, así que pensé en publicar cómo trato los argumentos de línea de comandos en los archivos por lotes.

Esta técnica tiene un poco de sobrecarga, como verá, pero hace que mis archivos por lotes sean muy fáciles de entender y de implementar rápidamente. Además de soportar las siguientes estructuras:

>template.bat [-f] [--flag] [/f] [--namedvalue value] arg1 [arg2][arg3][...]

La cuestión es tener el :init, :parsey :main funciones.

Ejemplo de uso

>template.bat /?
test v1.23
This is a sample batch file template,
providing command-line arguments and flags.

USAGE:
test.bat [flags] "required argument" "optional argument"

/?, --help           shows this help
/v, --version        shows the version
/e, --verbose        shows detailed output
-f, --flag value     specifies a named parameter value

>template.bat          <- throws missing argument error
(same as /?, plus..)
****                                   ****
****    MISSING "REQUIRED ARGUMENT"    ****
****                                   ****

>template.bat -v
1.23

>template.bat --version
test v1.23
This is a sample batch file template,
providing command-line arguments and flags.

>template.bat -e arg1
**** DEBUG IS ON
UnNamedArgument:    "arg1"
UnNamedOptionalArg: not provided
NamedFlag:          not provided

>template.bat --flag "my flag" arg1 arg2
UnNamedArgument:    "arg1"
UnNamedOptionalArg: "arg2"
NamedFlag:          "my flag"

>template.bat --verbose "argument #1" --flag "my flag" second
**** DEBUG IS ON
UnNamedArgument:    "argument #1"
UnNamedOptionalArg: "second"
NamedFlag:          "my flag"

template.bat

@::!/dos/rocks
@echo off
goto :init

:header
    echo %__NAME% v%__VERSION%
    echo This is a sample batch file template,
    echo providing command-line arguments and flags.
    echo.
    goto :eof

:usage
    echo USAGE:
    echo   %__BAT_NAME% [flags] "required argument" "optional argument" 
    echo.
    echo.  /?, --help           shows this help
    echo.  /v, --version        shows the version
    echo.  /e, --verbose        shows detailed output
    echo.  -f, --flag value     specifies a named parameter value
    goto :eof

:version
    if "%~1"=="full" call :header & goto :eof
    echo %__VERSION%
    goto :eof

:missing_argument
    call :header
    call :usage
    echo.
    echo ****                                   ****
    echo ****    MISSING "REQUIRED ARGUMENT"    ****
    echo ****                                   ****
    echo.
    goto :eof

:init
    set "__NAME=%~n0"
    set "__VERSION=1.23"
    set "__YEAR=2017"

    set "__BAT_FILE=%~0"
    set "__BAT_PATH=%~dp0"
    set "__BAT_NAME=%~nx0"

    set "OptHelp="
    set "OptVersion="
    set "OptVerbose="

    set "UnNamedArgument="
    set "UnNamedOptionalArg="
    set "NamedFlag="

:parse
    if "%~1"=="" goto :validate

    if /i "%~1"=="/?"         call :header & call :usage "%~2" & goto :end
    if /i "%~1"=="-?"         call :header & call :usage "%~2" & goto :end
    if /i "%~1"=="--help"     call :header & call :usage "%~2" & goto :end

    if /i "%~1"=="/v"         call :version      & goto :end
    if /i "%~1"=="-v"         call :version      & goto :end
    if /i "%~1"=="--version"  call :version full & goto :end

    if /i "%~1"=="/e"         set "OptVerbose=yes"  & shift & goto :parse
    if /i "%~1"=="-e"         set "OptVerbose=yes"  & shift & goto :parse
    if /i "%~1"=="--verbose"  set "OptVerbose=yes"  & shift & goto :parse

    if /i "%~1"=="--flag"     set "NamedFlag=%~2"   & shift & shift & goto :parse

    if not defined UnNamedArgument     set "UnNamedArgument=%~1"     & shift & goto :parse
    if not defined UnNamedOptionalArg  set "UnNamedOptionalArg=%~1"  & shift & goto :parse

    shift
    goto :parse

:validate
    if not defined UnNamedArgument call :missing_argument & goto :end

:main
    if defined OptVerbose (
        echo **** DEBUG IS ON
    )

    echo UnNamedArgument:    "%UnNamedArgument%"

    if defined UnNamedOptionalArg      echo UnNamedOptionalArg: "%UnNamedOptionalArg%"
    if not defined UnNamedOptionalArg  echo UnNamedOptionalArg: not provided

    if defined NamedFlag               echo NamedFlag:          "%NamedFlag%"
    if not defined NamedFlag           echo NamedFlag:          not provided

:end
    call :cleanup
    exit /B

:cleanup
    REM The cleanup function is only really necessary if you
    REM are _not_ using SETLOCAL.
    set "__NAME="
    set "__VERSION="
    set "__YEAR="

    set "__BAT_FILE="
    set "__BAT_PATH="
    set "__BAT_NAME="

    set "OptHelp="
    set "OptVersion="
    set "OptVerbose="

    set "UnNamedArgument="
    set "UnNamedArgument2="
    set "NamedFlag="

    goto :eof

23
2017-07-13 03:32



Mantengamos esto simple.

Aquí está el archivo .cmd.

@echo off
rem this file is named echo_3params.cmd
echo %1
echo %2
echo %3
set v1=%1
set v2=%2
set v3=%3
echo v1 equals %v1%
echo v2 equals %v2%
echo v3 equals %v3%

Aquí hay 3 llamadas de la línea de comando.

C:\Users\joeco>echo_3params 1abc 2 def  3 ghi
1abc
2
def
v1 equals 1abc
v2 equals 2
v3 equals def

C:\Users\joeco>echo_3params 1abc "2 def"  "3 ghi"
1abc
"2 def"
"3 ghi"
v1 equals 1abc
v2 equals "2 def"
v3 equals "3 ghi"

C:\Users\joeco>echo_3params 1abc '2 def'  "3 ghi"
1abc
'2
def'
v1 equals 1abc
v2 equals '2
v3 equals def'

C:\Users\joeco>

18
2017-12-31 17:59