Necesito pasar una identificación y una contraseña a un archivo por lotes en el momento de la ejecución en lugar de codificarlos en el archivo.
Así es como se ve la línea de comando:
test.cmd admin [email protected] > test-log.txt
Otro consejo útil es utilizar %*
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 admin password foo bar
Puede que tenga la sintaxis ligeramente incorrecta, pero esta es la idea general.
Así es como lo hice:
@fake-command /u %1 /p %2
Así es como se ve el comando:
test.cmd admin [email protected] > test-log.txt
Se %1
aplica al primer parámetro %2
y (y aquí está la parte complicada) se aplica al segundo. Puede tener hasta 9 parámetros pasados de esta manera.
Si desea manejar de manera 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
El acceso a los parámetros de lote puede ser simple con% 1,% 2, ...% 9 o también% *,
pero solo si el contenido es simple.
No existe una forma sencilla 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, ya que una de las &
está fuera de las comillas.
Se puede solucionar leyendo de un archivo temporal una versión remarcada 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 consiste en habilitar echo on
y expandir% 1 después de una rem
declaración (también funciona con %2 .. %*
).
Por lo que incluso "&"&
podría hacerse eco sin producir un error, como se comenta.
Pero para poder redirigir la salida del echo on
, necesita los dos bucles for.
Los caracteres adicionales * #
se utilizan para estar a salvo de contenidos como /?
(mostraría la ayuda para REM
).
O un signo de intercalación ^ al final de la línea podría funcionar como un carácter de varias líneas, incluso después de un rem
.
Luego, lea la salida del parámetro rem del archivo, pero con cuidado.
El FOR / F debería funcionar con la expansión retardada desactivada, de lo contrario, los contenidos con "!" sería destruido.
Después de eliminar los caracteres adicionales param1
, lo tienes.
Y para utilizar param1
de forma segura, habilite la expansión retrasada.
Sí, y no olvides usar variables como %%1
cuando usas if
y for
y la pandilla.
Si olvida el doble %
, estará sustituyendo argumentos de línea de comando (posiblemente nulos) y recibirá algunos mensajes de error bastante confusos.
No hay necesidad de complicarlo. Es simplemente el comando% 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 CUALQUIER. 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 encarga 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 a medida que se copian, omita el Q
parámetro.
Un amigo me estaba preguntando sobre este tema recientemente, así que pensé en publicar cómo manejo los argumentos de la línea de comandos en 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 rápidos de implementar. Además de soportar las siguientes estructuras:
>template.bat [-f] [--flag] [/f] [--namedvalue value] arg1 [arg2][arg3][...]
El jist de que está teniendo los :init
, :parse
y :main
funciones.
Uso de ejemplo
>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
@ECHO OFF
:Loop
IF "%1"=="" GOTO Continue
SHIFT
GOTO Loop
:Continue
Nota: IF "%1"==""
causará problemas si %1
se incluye entre comillas.
En ese caso, utilice IF [%1]==[]
o, en NT 4 (SP6) y solo en versiones posteriores, en su IF "%~1"==""
lugar.
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 desde 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>
FOR %%A IN (%*) DO (
REM Now your batch file handles %%A instead of %1
REM No need to use SHIFT anymore.
ECHO %%A
)
Esto recorre los parámetros del lote (% *) ya sea que estén cotizados o no, luego hace eco de cada parámetro.
En archivo por lotes
set argument1=%1
set argument2=%2
echo %argument1%
echo %argument2%
%1
y %2
devuelve el primer y segundo valor de los argumentos respectivamente.
Y en la línea de comando, pasa el argumento
Directory> batchFileName admin [email protected]
La salida será
admin
[email protected]
Escribí un script read_params simple que se puede llamar como una función (o externa .bat
) y pondrá todas las variables en el entorno actual. No modificará los parámetros originales porque la función se está call
editando con una copia de los parámetros originales.
Por ejemplo, dado el siguiente comando:
myscript.bat some -random=43 extra -greeting="hello world" fluff
myscript.bat
podría usar las variables después de llamar a la función:
call :read_params %*
echo %random%
echo %greeting%
Esta es la función:
:read_params
if not %1/==/ (
if not "%__var%"=="" (
if not "%__var:~0,1%"=="-" (
endlocal
goto read_params
)
endlocal & set %__var:~1%=%~1
) else (
setlocal & set __var=%~1
)
shift
goto read_params
)
exit /B
Limitaciones
-force
. Podría usar, -force=true
pero no puedo pensar en una forma de permitir valores en blanco sin conocer una lista de parámetros de antemano que no tendrán un valor.Registro de cambios
-
antes los parámetros.Para hacer referencia a una variable establecida en la línea de comando, necesitaría usar, %a%
por ejemplo:
set a=100
echo %a%
rem output = 100
Nota: esto funciona para Windows 7 pro.
Inspirado por una respuesta de @Jon en otra parte, he elaborado un algoritmo más general para extraer parámetros con nombre, valores opcionales e interruptores.
Digamos que queremos implementar una utilidad foobar
. Requiere un comando inicial. Tiene un parámetro opcional --foo
que toma un valor opcional (que no puede ser otro parámetro, por supuesto); si falta el valor, el valor predeterminado es default
. También tiene un parámetro opcional --bar
que toma un valor requerido . Por último, puede tomar una bandera --baz
sin valor permitido. Ah, y estos parámetros pueden venir en cualquier orden.
En otras palabras, se ve así:
foobar <command> [--foo [<fooval>]] [--bar <barval>] [--baz]
He aquí una solución:
@ECHO OFF
SETLOCAL
REM FooBar parameter demo
REM By Garret Wilson
SET CMD=%~1
IF "%CMD%" == "" (
GOTO usage
)
SET FOO=
SET DEFAULT_FOO=default
SET BAR=
SET BAZ=
SHIFT
:args
SET PARAM=%~1
SET ARG=%~2
IF "%PARAM%" == "--foo" (
SHIFT
IF NOT "%ARG%" == "" (
IF NOT "%ARG:~0,2%" == "--" (
SET FOO=%ARG%
SHIFT
) ELSE (
SET FOO=%DEFAULT_FOO%
)
) ELSE (
SET FOO=%DEFAULT_FOO%
)
) ELSE IF "%PARAM%" == "--bar" (
SHIFT
IF NOT "%ARG%" == "" (
SET BAR=%ARG%
SHIFT
) ELSE (
ECHO Missing bar value. 1>&2
ECHO:
GOTO usage
)
) ELSE IF "%PARAM%" == "--baz" (
SHIFT
SET BAZ=true
) ELSE IF "%PARAM%" == "" (
GOTO endargs
) ELSE (
ECHO Unrecognized option %1. 1>&2
ECHO:
GOTO usage
)
GOTO args
:endargs
ECHO Command: %CMD%
IF NOT "%FOO%" == "" (
ECHO Foo: %FOO%
)
IF NOT "%BAR%" == "" (
ECHO Bar: %BAR%
)
IF "%BAZ%" == "true" (
ECHO Baz
)
REM TODO do something with FOO, BAR, and/or BAZ
GOTO :eof
:usage
ECHO FooBar
ECHO Usage: foobar ^<command^> [--foo [^<fooval^>]] [--bar ^<barval^>] [--baz]
EXIT /B 1
SETLOCAL
para que las variables no escapen al entorno de llamada.SET FOO=
, etc. en caso de que alguien las haya definido en el entorno de llamada.%~1
para eliminar comillas.IF "%ARG%" == ""
and not IF [%ARG%] == []
because [
and ]
don't play será en absoluto con valores que terminen en un espacio.SHIFT
dentro de un IF
bloque, los argumentos actuales como %~1
no se actualizan porque se determinan cuando IF
se analiza. Podrías usar %~1
y %~2
dentro del IF
bloque, pero sería confuso porque tienes un SHIFT
. Puede poner el SHIFT
al final del bloque para mayor claridad, pero eso podría perderse y / o confundir a las personas también. Así que "capturar" %~1
y %~1
fuera del bloque parece lo mejor.IF NOT "%ARG:~0,2%" == "--"
.SHIFT
cuando utilice uno de los parámetros.SET FOO=%DEFAULT_FOO%
es lamentable, pero la alternativa sería agregar un IF "%FOO%" == "" SET FOO=%DEFAULT_FOO%
fuera del IF NOT "%ARG%" == ""
bloque. Sin embargo, debido a que todavía está dentro del IF "%PARAM%" == "--foo"
bloque, el %FOO%
valor se habría evaluado y establecido antes de que usted ingresara al bloque, por lo que nunca detectaría que tanto el --foo
parámetro estaba presente como que %FOO%
faltaba el valor.ECHO Missing bar value. 1>&2
envía el mensaje de error a stderr.ECHO:
o una de las variaciones.Cree un nuevo archivo por lotes (ejemplo: openclass.bat) y escriba esta línea en el archivo:
java %~n1
Luego coloque el archivo por lotes en, digamos, la carpeta system32, vaya a su archivo de clase Java, haga clic derecho, Propiedades, Abrir con ..., luego busque su archivo por lotes, selecciónelo y listo ...
Esto funciona para mi.
PD: no puedo encontrar una manera de cerrar la ventana cmd cuando cierro la clase Java. Por ahora...
Para usar el bucle, obtenga todos los argumentos y en lotes puros:
Obs: Para usar sin:?*&<>
@echo off && setlocal EnableDelayedExpansion
for %%Z in (%*)do set "_arg_=%%Z" && set/a "_cnt+=1+0" && (
call set "_arg_[!_cnt!]=!_arg_!" && for /l %%l in (!_cnt! 1 !_cnt!
)do echo/ The argument n:%%l is: !_arg_[%%l]!
)
goto :eof
Su código está listo para hacer algo con el número de argumento donde lo necesite, como ...
@echo off && setlocal EnableDelayedExpansion
for %%Z in (%*)do set "_arg_=%%Z" && set/a "_cnt+=1+0" && call set "_arg_[!_cnt!]=!_arg_!"
fake-command /u !_arg_[1]! /p !_arg_[2]! > test-log.txt
Solución simple (aunque la pregunta es antigua)
Test1.bat
echo off
echo "Batch started"
set arg1=%1
echo "arg1 is %arg1%"
echo on
pause
CallTest1.bat
call "C:\Temp\Test1.bat" pass123
producción
YourLocalPath>call "C:\Temp\test.bat" pass123
YourLocalPath>echo off
"Batch started"
"arg1 is pass123"
YourLocalPath>pause
Press any key to continue . . .
Donde YourLocalPath es la ruta del directorio actual.
Para mantener las cosas simples, almacene el comando param en variable y use variable para comparar.
No solo es simple de escribir, sino que también es simple de mantener, por lo que si luego otra persona o usted lee su guión después de un largo período de tiempo, será fácil de entender y mantener.
Para escribir código en línea: vea otras respuestas.
Si prefiere pasar los argumentos en un par clave-valor, puede usar algo como esto:
@echo off
setlocal enableDelayedExpansion
::::: asigning arguments as a key-value pairs:::::::::::::
set counter=0
for %%# in (%*) do (
set /a counter=counter+1
set /a even=counter%%2
if !even! == 0 (
echo setting !prev! to %%#
set "!prev!=%%~#"
)
set "prev=%%~#"
)
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: showing the assignments
echo %one% %two% %three% %four% %five%
endlocal
Y un ejemplo:
c:>argumentsDemo.bat one 1 "two" 2 three 3 four 4 "five" 5
1 2 3 4 5
También puede establecer algunas variables de entorno de antemano. Se puede hacer configurándolos en la consola o configurándolos desde mi computadora :
@echo off
if defined variable1 (
echo %variable1%
)
if defined variable2 (
echo %variable2%
)
y llamándolo como:
c:\>set variable1=1
c:\>set variable2=2
c:\>argumentsTest.bat
1
2
También puede apuntar a un archivo donde los valores necesarios están preestablecidos. Si este es el guión:
@echo off
setlocal
::::::::::
set "VALUES_FILE=E:\scripts\values.txt"
:::::::::::
for /f "usebackq eol=: tokens=* delims=" %%# in ("%VALUES_FILE%") do set "%%#"
echo %key1% %key2% %some_other_key%
endlocal
y el archivo de valores es este:
:::: use EOL=: in the FOR loop to use it as a comment
key1=value1
key2=value2
:::: do not left spaces arround the =
:::: or at the begining of the line
some_other_key=something else
and_one_more=more
la salida de llamarlo será:
valor1 valor2 algo más
Por supuesto, puede combinar todos los enfoques. Verifique también la sintaxis de los argumentos , shift
La estrella de HGTV, Christina Hall, revela que le diagnosticaron envenenamiento por mercurio y plomo, probablemente debido a su trabajo como manipuladora de casas.
Recientemente salió a la luz un informe policial que acusa a la estrella de 'Love Is Blind', Brennon, de violencia doméstica. Ahora, Brennon ha respondido a los reclamos.
Conozca cómo Wynonna Judd se dio cuenta de que ahora es la matriarca de la familia mientras organizaba la primera celebración de Acción de Gracias desde que murió su madre, Naomi Judd.
Descubra por qué un destacado experto en lenguaje corporal cree que es fácil trazar "tales paralelismos" entre la princesa Kate Middleton y la princesa Diana.
Los inodoros arrojan columnas de aerosol invisibles con cada descarga. ¿Como sabemos? La prueba fue capturada por láseres de alta potencia.
Air travel is far more than getting from point A to point B safely. How much do you know about the million little details that go into flying on airplanes?
The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!
¿Sigue siendo efectivo ese lote de repelente de insectos que te quedó del verano pasado? Si es así, ¿por cuánto tiempo?
Tapas elásticas de silicona de Tomorrow's Kitchen, paquete de 12 | $14 | Amazonas | Código promocional 20OFFKINJALids son básicamente los calcetines de la cocina; siempre perdiéndose, dejando contenedores huérfanos que nunca podrán volver a cerrarse. Pero, ¿y si sus tapas pudieran estirarse y adaptarse a todos los recipientes, ollas, sartenes e incluso frutas en rodajas grandes que sobran? Nunca más tendrás que preocuparte por perder esa tapa tan específica.
Hemos pirateado algunas ciudades industriales en esta columna, como Los Ángeles y Las Vegas. Ahora es el momento de una ciudad militar-industrial-compleja.
Un minorista está enlatando su sección de tallas grandes. Pero no están tomando la categoría solo en línea o descontinuándola por completo.
Entiendo totalmente, completamente si tienes una relación difícil con los animales de peluche. Son lindos, tienen valor sentimental y es difícil separarse de ellos.
El equipo está a la espera de las medallas que ganó en los Juegos Olímpicos de Invierno de 2022 en Beijing, ya que se está resolviendo un caso de dopaje que involucra a la patinadora artística rusa Kamila Valieva.
Miles de compradores de Amazon recomiendan la funda de almohada de seda Mulberry, y está a la venta en este momento. La funda de almohada de seda viene en varios colores y ayuda a mantener el cabello suave y la piel clara. Compre las fundas de almohada de seda mientras tienen hasta un 46 por ciento de descuento en Amazon
El jueves se presentó una denuncia de delito menor amenazante agravado contra Joe Mixon.
El Departamento de Policía de Lafayette comenzó a investigar a un profesor de la Universidad de Purdue en diciembre después de recibir varias denuncias de un "hombre sospechoso que se acercaba a una mujer".
Al igual que el mundo que nos rodea, el lenguaje siempre está cambiando. Mientras que en eras anteriores los cambios en el idioma ocurrían durante años o incluso décadas, ahora pueden ocurrir en cuestión de días o incluso horas.
Estoy de vuelta por primera vez en seis años. No puedo decirte cuánto tiempo he estado esperando esto.
“And a river went out of Eden to water the garden, and from thence it was parted and became into four heads” Genesis 2:10. ? The heart is located in the middle of the thoracic cavity, pointing eastward.
Creo, un poco tarde en la vida, en dar oportunidades a la gente. Generosamente.