Respuestas:
Nota: Asumo archivos por lotes de Windows, ya que la mayoría de la gente parece no darse cuenta de que existen diferencias significativas y simplemente llama ciegamente a todo con texto gris sobre fondo negro DOS. Sin embargo, la primera variante también debería funcionar en DOS.
La forma más sencilla de hacer esto es simplemente poner las variables en un archivo por lotes, cada una con su propia set
declaración:
set var1=value1
set var2=value2
...
y en tu lote principal:
call config.cmd
Por supuesto, eso también permite que las variables se creen condicionalmente o dependiendo de los aspectos del sistema, por lo que es bastante versátil. Sin embargo, el código arbitrario se puede ejecutar allí y si hay un error de sintaxis, su lote principal también se cerrará. En el mundo UNIX, esto parece ser bastante común, especialmente para los shells. Y si lo piensas, autoexec.bat
es nada más.
Otra forma sería algún tipo de var=value
pares en el archivo de configuración:
var1=value1
var2=value2
...
A continuación, puede utilizar el siguiente fragmento para cargarlos:
for /f "delims=" %%x in (config.txt) do (set "%%x")
Esto utiliza un truco similar al anterior, es decir, solo usar set
en cada línea. Las citas están ahí para escapar cosas como <
, >
, &
, |
. Sin embargo, ellos mismos se romperán cuando se utilicen comillas en la entrada. Además, siempre debe tener cuidado al procesar datos en variables almacenadas con tales caracteres.
En general, me parece bastante imposible escapar automáticamente de una entrada arbitraria para no causar dolores de cabeza o problemas en los archivos por lotes. Al menos todavía no encontré la manera de hacerlo. Por supuesto, con la primera solución le está pasando esa responsabilidad al que escribe el archivo de configuración.
Si el archivo de configuración externo también es un archivo por lotes válido, puede usar:
call externalconfig.bat
dentro de su guión. Intente crear el siguiente a.bat:
@echo off
call b.bat
echo %MYVAR%
y b.bat:
set MYVAR=test
Ejecutar a.bat debería generar una salida:
test
call
, que por cierto es síncrono), dice "el proceso no puede acceder al archivo porque está siendo usado" y no puede ser invocado.
Batch utiliza los corchetes menor que y mayor que como conductos de entrada y salida.
>file.ext
Usar solo un corchete de salida como el anterior sobrescribirá toda la información en ese archivo.
>>file.ext
El uso del corchete doble derecho agregará la siguiente línea al archivo.
(
echo
echo
)<file.ext
Esto ejecutará los parámetros en función de las líneas del archivo. En este caso, estamos usando dos líneas que se escribirán usando "echo". El corchete izquierdo que toca el paréntesis derecho significa que la información de ese archivo se canalizará a esas líneas.
He compilado un archivo de lectura / escritura de solo ejemplo. A continuación se muestra el archivo dividido en secciones para explicar qué hace cada parte.
@echo off
echo TEST R/W
set SRU=0
SRU puede ser cualquier cosa en este ejemplo. En realidad, lo estamos configurando para evitar un bloqueo si presiona Enter demasiado rápido.
set /p SRU=Skip Save? (y):
if %SRU%==y goto read
set input=1
set input2=2
set /p input=INPUT:
set /p input2=INPUT2:
Ahora, necesitamos escribir las variables en un archivo.
(echo %input%)> settings.cdb
(echo %input2%)>> settings.cdb
pause
Utilizo .cdb como forma abreviada de "Base de datos de comandos". Puedes usar cualquier extensión. La siguiente sección es probar el código desde cero. No queremos usar las variables establecidas que se ejecutaron al principio del archivo, en realidad queremos que se carguen DESDE settings.cdb que acabamos de escribir.
:read
(
set /p input=
set /p input2=
)<settings.cdb
Entonces, acabamos de canalizar las dos primeras líneas de información que escribió al principio del archivo (que tiene la opción de omitir la configuración de las líneas para verificar que esté funcionando) para configurar las variables de input y input2.
echo %input%
echo %input2%
pause
if %input%==1 goto newecho
pause
exit
:newecho
echo If you can see this, good job!
pause
exit
Esto muestra la información que se estableció mientras settings.cdb se canalizó entre paréntesis. Como motivador adicional para un buen trabajo, presionar Enter y establecer los valores predeterminados que establecimos anteriormente como "1" devolverá un mensaje de buen trabajo. Usar los tubos de soporte va en ambos sentidos, y es mucho más fácil que configurar el "FOR". :)
Entonces, ¿tienes que hacer esto bien ?:
@echo off
echo text shizzle
echo.
echo pause^>nul (press enter)
pause>nul
REM writing to file
(
echo XD
echo LOL
)>settings.cdb
cls
REM setting the variables out of the file
(
set /p input=
set /p input2=
)<settings.cdb
cls
REM echo'ing the variables
echo variables:
echo %input%
echo %input2%
pause>nul
if %input%==XD goto newecho
DEL settings.cdb
exit
:newecho
cls
echo If you can see this, good job!
DEL settings.cdb
pause>nul
exit
:: savevars.bat
:: Use $ to prefix any important variable to save it for future runs.
@ECHO OFF
SETLOCAL
REM Load variables
IF EXIST config.txt FOR /F "delims=" %%A IN (config.txt) DO SET "%%A"
REM Change variables
IF NOT DEFINED $RunCount (
SET $RunCount=1
) ELSE SET /A $RunCount+=1
REM Display variables
SET $
REM Save variables
SET $>config.txt
ENDLOCAL
PAUSE
EXIT /B
Salida:
$ RunCount = 1
$ RunCount = 2
$ RunCount = 3
La técnica descrita anteriormente también se puede utilizar para compartir variables entre varios archivos por lotes.
Un tema un poco viejo, pero tuve la misma pregunta hace unos días y se me ocurrió otra idea (tal vez a alguien todavía le resulte útil)
Por ejemplo, puede hacer un config.bat con diferentes temas (familia, tamaño, color, animales) y aplicarlos individualmente en cualquier orden en cualquier lugar que desee en sus scripts por lotes:
@echo off
rem Empty the variable to be ready for label config_all
set config_all_selected=
rem Go to the label with the parameter you selected
goto :config_%1
REM This next line is just to go to end of file
REM in case that the parameter %1 is not set
goto :end
REM next label is to jump here and get all variables to be set
:config_all
set config_all_selected=1
:config_family
set mother=Mary
set father=John
set sister=Anna
rem This next line is to skip going to end if config_all label was selected as parameter
if not "%config_all_selected%"=="1" goto :end
:config_test
set "test_parameter_all=2nd set: The 'all' parameter WAS used before this echo"
if not "%config_all_selected%"=="1" goto :end
:config_size
set width=20
set height=40
if not "%config_all_selected%"=="1" goto :end
:config_color
set first_color=blue
set second_color=green
if not "%config_all_selected%"=="1" goto :end
:config_animals
set dog=Max
set cat=Miau
if not "%config_all_selected%"=="1" goto :end
:end
Después de eso, puede usarlo en cualquier lugar llamando completamente con 'call config.bat all' o llamando solo a partes de él (vea el ejemplo a continuación) La idea aquí es que a veces es más útil cuando tiene la opción de no llamar a todo al una vez. Es posible que algunas variables no desee que se le llame todavía para poder llamarlas más tarde.
Ejemplo test.bat
@echo off
rem This is added just to test the all parameter
set "test_parameter_all=1st set: The 'all' parameter was NOT used before this echo"
call config.bat size
echo My birthday present had a width of %width% and a height of %height%
call config.bat family
call config.bat animals
echo Yesterday %father% and %mother% surprised %sister% with a cat named %cat%
echo Her brother wanted the dog %dog%
rem This shows you if the 'all' parameter was or not used (just for testing)
echo %test_parameter_all%
call config.bat color
echo His lucky color is %first_color% even if %second_color% is also nice.
echo.
pause
Espero que ayude la forma en que otros me ayudan aquí con sus respuestas.
Una versión corta de lo anterior:
config.bat
@echo off
set config_all_selected=
goto :config_%1
goto :end
:config_all
set config_all_selected=1
:config_family
set mother=Mary
set father=John
set daughter=Anna
if not "%config_all_selected%"=="1" goto :end
:config_size
set width=20
set height=40
if not "%config_all_selected%"=="1" goto :end
:end
test.bat
@echo off
call config.bat size
echo My birthday present had a width of %width% and a height of %height%
call config.bat family
echo %father% and %mother% have a daughter named %daughter%
echo.
pause
Buen día.
No olvidemos los buenos parámetros antiguos. Al iniciar su archivo * .bat o * .cmd, puede agregar hasta nueve parámetros después del nombre del archivo de comando:
call myscript.bat \\path\to\my\file.ext type
call myscript.bat \\path\to\my\file.ext "Del /F"
El myscript.bat podría ser algo como esto:
@Echo Off
Echo The path of this scriptfile %~0
Echo The name of this scriptfile %~n0
Echo The extension of this scriptfile %~x0
Echo.
If "%~2"=="" (
Echo Parameter missing, quitting.
GoTo :EOF
)
If Not Exist "%~1" (
Echo File does not exist, quitting.
GoTo :EOF
)
Echo Going to %~2 this file: %~1
%~2 "%~1"
If %errorlevel% NEQ 0 (
Echo Failed to %~2 the %~1.
)
@Echo On
c:\>c:\bats\myscript.bat \\server\path\x.txt type
The path of this scriptfile c:\bats\myscript.bat
The name of this scriptfile myscript
The extension of this scriptfile .bat
Going to type this file: \\server\path\x.txt
This is the content of the file:
Some alphabets: ABCDEFG abcdefg
Some numbers: 1234567890
c:\>c:\bats\myscript.bat \\server\path\x.txt "del /f "
The path of this scriptfile c:\bats\myscript.bat
The name of this scriptfile myscript
The extension of this scriptfile .bat
Going to del /f this file: \\server\path\x.txt
c:\>
Al intentar usar el método con una configuración ejecutable, noté que puede funcionar o NO, dependiendo de dónde se encuentre la llamada en el script:
llamar config.cmd
Sé que no tiene ningún sentido, pero para mí es un hecho. Cuando "call config.cmd" se encuentra en la parte superior de la secuencia de comandos, funciona, pero si se encuentra más adelante en la secuencia de comandos, no funciona.
Por no funciona, me refiero a que las variables no están configuradas en el script de llamada.
Muy muy extraño !!!!