Arquivo em lote inclui arquivo externo para variáveis

98

Tenho um arquivo em lote e desejo incluir um arquivo externo que contém algumas variáveis ​​(digamos, variáveis ​​de configuração). É possível?

Pablo
fonte
Implementação da mina: stackoverflow.com/questions/46147450/…
Andry

Respostas:

133

Nota: Estou assumindo os arquivos em lote do Windows, já que a maioria das pessoas parece não estar ciente de que existem diferenças significativas e simplesmente chamam tudo com texto cinza em fundo preto do DOS. No entanto, a primeira variante deve funcionar no DOS também.

Configuração executável

A maneira mais fácil de fazer isso é simplesmente colocar as variáveis ​​em um arquivo em lote, cada uma com sua própria setinstrução:

set var1=value1
set var2=value2
...

e em seu lote principal:

call config.cmd

Claro, isso também permite que variáveis ​​sejam criadas condicionalmente ou dependendo de aspectos do sistema, portanto, é muito versátil. No entanto, um código arbitrário pode ser executado lá e, se houver um erro de sintaxe, seu lote principal também será encerrado. No mundo UNIX, isso parece ser bastante comum, especialmente para shells. E se você pensar sobre isso, autoexec.batnada mais é.

Pares de chave / valor

Outra forma seria algum tipo de var=valuepares no arquivo de configuração:

var1=value1
var2=value2
...

Você pode então usar o seguinte snippet para carregá-los:

for /f "delims=" %%x in (config.txt) do (set "%%x")

Isso utiliza um truque semelhante ao anterior, ou seja, apenas usando setem cada linha. As citações estão lá para escapar coisas como <, >, &, |. No entanto, eles próprios quebram quando as aspas são usadas na entrada. Além disso, você sempre precisa ter cuidado ao processar dados em variáveis ​​armazenadas com esses caracteres.

Geralmente, o escape automático de entrada arbitrária para não causar dores de cabeça ou problemas em arquivos em lote parece praticamente impossível para mim. Pelo menos eu não encontrei uma maneira de fazer isso ainda. Claro, com a primeira solução, você está transferindo essa responsabilidade para quem está escrevendo o arquivo de configuração.

Joey
fonte
Isso não funcionou para mim, você pode verificar: stackoverflow.com/questions/46147450/…
Naguib Ihab
35

Se o arquivo de configuração externa também for um arquivo em lote válido, você pode apenas usar:

call externalconfig.bat

dentro do seu script. Tente criar o seguinte a.bat:

@echo off
call b.bat
echo %MYVAR%

e b.bat:

set MYVAR=test

Executar a.bat deve gerar saída:

test
chalup
fonte
Isso não funcionou para mim, você pode verificar: stackoverflow.com/questions/46147450/…
Naguib Ihab
Se estiver usando o arquivo de configuração em outro script em paralelo (chamando-o com call, que é btw síncrono), ele diz "o processo não pode acessar o arquivo porque está sendo usado" e não pode ser chamado.
domih de
2

O lote usa os colchetes menor que e maior que como canais de entrada e saída.

>file.ext

Usar apenas um colchete de saída como acima irá sobrescrever todas as informações naquele arquivo.

>>file.ext

Usar o colchete direito duplo adicionará a próxima linha ao arquivo.

(
echo
echo
)<file.ext

Isso executará os parâmetros com base nas linhas do arquivo. Neste caso, estamos usando duas linhas que serão digitadas com "echo". O colchete esquerdo tocando o colchete direito significa que as informações desse arquivo serão canalizadas para essas linhas.

Eu compilei um arquivo de leitura / gravação somente de exemplo. Abaixo está o arquivo dividido em seções para explicar o que cada parte faz.

@echo off
echo TEST R/W
set SRU=0

SRU pode ser qualquer coisa neste exemplo. Na verdade, estamos configurando para evitar um travamento se você pressionar Enter muito 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: 

Agora, precisamos gravar as variáveis ​​em um arquivo.

(echo %input%)> settings.cdb
(echo %input2%)>> settings.cdb
pause

Eu uso .cdb como uma forma abreviada de "Banco de dados de comandos". Você pode usar qualquer extensão. A próxima seção é testar o código do zero. Não queremos usar as variáveis ​​definidas que foram executadas no início do arquivo, na verdade queremos que elas sejam carregadas DE settings.cdb que acabamos de escrever.

:read
(
set /p input=
set /p input2=
)<settings.cdb

Portanto, apenas canalizamos as duas primeiras linhas de informações que você escreveu no início do arquivo (que você tem a opção de pular a configuração das linhas para verificar se está funcionando) para definir as variáveis ​​de entrada e entrada2.

echo %input%
echo %input2%
pause
if %input%==1 goto newecho
pause
exit

:newecho
echo If you can see this, good job!
pause
exit

Isso exibe as informações que foram definidas enquanto settings.cdb foi colocado entre parênteses. Como um motivador extra de bom trabalho, pressionar enter e definir os valores padrão que definimos anteriormente como "1" retornará uma mensagem de bom trabalho. Usar os tubos de suporte é para os dois lados e é muito mais fácil do que definir as coisas "PARA". :)

Sev3nClouds
fonte
1

Então você só precisa fazer isso certo ?:

@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
THEfixer
fonte
0
:: 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

Resultado:

$ RunCount = 1

$ RunCount = 2

$ RunCount = 3

A técnica descrita acima também pode ser usada para compartilhar variáveis ​​entre vários arquivos em lote.

Fonte: http://www.incodesystems.com/products/batchfi1.htm

Amr Ali
fonte
0

Assunto meio antigo, mas eu tive a mesma pergunta alguns dias atrás e eu tive outra ideia (talvez alguém ainda ache útil)

Por exemplo, você pode fazer um config.bat com diferentes assuntos (família, tamanho, cor, animais) e aplicá-los individualmente em qualquer ordem que você quiser em seus scripts de lote:

@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

Depois disso, você pode usá-lo em qualquer lugar chamando totalmente com 'call config.bat all' ou chamando apenas partes dele (veja o exemplo abaixo) A ideia aqui é que às vezes é mais útil quando você tem a opção de não chamar tudo em uma vez. Algumas variáveis ​​talvez você não queira que sejam chamadas ainda, para que possa chamá-las mais tarde.

Exemplo 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 ajude a maneira como outros me ajudam aqui com suas respostas.

Uma versão curta do acima:

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

Dia bom.

Sorin
fonte
-2

Não vamos esquecer os bons e velhos parâmetros. Ao iniciar seu arquivo * .bat ou * .cmd, você pode adicionar até nove parâmetros após o nome do arquivo de comando:

call myscript.bat \\path\to\my\file.ext type
call myscript.bat \\path\to\my\file.ext "Del /F"

Script de exemplo

O myscript.bat pode ser algo assim:

@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

Saída de exemplo

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:\>
Ciove
fonte
-3

Ao tentar usar o método com configuração executável, percebi que pode funcionar ou NÃO, dependendo de onde a chamada está localizada no script:

chamar config.cmd

Sei que não faz sentido, mas para mim é um fato. Quando "call config.cmd" está localizado na parte superior do script, ele funciona, mas não funciona mais adiante no script.

Por não funcionar, quero dizer que a variável não foi definida no script de chamada.

Muito, muito estranho !!!!

phil ten
fonte