批处理文件包含变量的外部文件

发布于 2024-08-31 09:17:59 字数 48 浏览 8 评论 0原文

我有一个批处理文件,我想包含一个包含一些变量(例如配置变量)的外部文件。是否可以?

I have a batch file and I want to include an external file containing some variables (say configuration variables). Is it possible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

夏の忆 2024-09-07 09:17:59

注意:我假设 Windows 批处理文件,因为大多数人似乎没有意识到存在显着差异,只是盲目地将黑色背景上灰色文本的所有内容称为 DOS。尽管如此,第一个变体应该也可以在 DOS 中运行。

可执行配置

最简单的方法是将变量本身放入批处理文件中,每个变量都有自己的 set 语句:

set var1=value1
set var2=value2
...

并在主批处理中:

call config.cmd

当然,这也可以创建变量有条件地或取决于系统的各个方面,因此它非常通用。但是,任意代码都可以在那里运行,如果存在语法错误,那么您的主批处理也将退出。在 UNIX 世界中,这似乎相当常见,尤其是对于 shell。如果你仔细想想,autoexec.bat 就是这样。

键/值对

另一种方法是在配置文件中使用某种 var=value 对:

var1=value1
var2=value2
...

然后您可以使用以下代码片段来加载它们:

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

这使用了与之前类似的技巧,即仅使用 < code>set 每行。引号是用来转义 <>&| 等内容的。但是,当输入中使用引号时,它们本身就会中断。此外,在进一步处理使用此类字符存储的变量中的数据时,您始终需要小心。

一般来说,自动转义任意输入以在批处理文件中不引起头痛或问题对我来说似乎是几乎不可能的。至少我还没有找到办法。当然,使用第一个解决方案时,您将这一责任推给了编写配置文件的人。

Note: I'm assuming Windows batch files as most people seem to be unaware that there are significant differences and just blindly call everything with grey text on black background DOS. Nevertheless, the first variant should work in DOS as well.

Executable configuration

The easiest way to do this is to just put the variables in a batch file themselves, each with its own set statement:

set var1=value1
set var2=value2
...

and in your main batch:

call config.cmd

Of course, that also enables variables to be created conditionally or depending on aspects of the system, so it's pretty versatile. However, arbitrary code can run there and if there is a syntax error, then your main batch will exit too. In the UNIX world this seems to be fairly common, especially for shells. And if you think about it, autoexec.bat is nothing else.

Key/value pairs

Another way would be some kind of var=value pairs in the configuration file:

var1=value1
var2=value2
...

You can then use the following snippet to load them:

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

This utilizes a similar trick as before, namely just using set on each line. The quotes are there to escape things like <, >, &, |. However, they will themselves break when quotes are used in the input. Also you always need to be careful when further processing data in variables stored with such characters.

Generally, automatically escaping arbitrary input to cause no headaches or problems in batch files seems pretty impossible to me. At least I didn't find a way to do so yet. Of course, with the first solution you're pushing that responsibility to the one writing the config file.

梦醒灬来后我 2024-09-07 09:17:59

如果外部配置文件也是有效的批处理文件,您可以

call externalconfig.bat

在脚本中使用:。尝试创建以下 a.bat:

@echo off
call b.bat
echo %MYVAR%

和 b.bat:

set MYVAR=test

运行 a.bat 应生成输出:

test

If the external configuration file is also valid batch file, you can just use:

call externalconfig.bat

inside your script. Try creating following a.bat:

@echo off
call b.bat
echo %MYVAR%

and b.bat:

set MYVAR=test

Running a.bat should generate output:

test
泪痕残 2024-09-07 09:17:59

Batch 使用小于和大于括号作为输入和输出管道。

>file.ext

仅使用一个像上面这样的输出括号将覆盖该文件中的所有信息。

>>file.ext

使用双右括号会将下一行添加到文件中。

(
echo
echo
)<file.ext

这将根据文件的行执行参数。在本例中,我们使用将使用“echo”键入的两行。左括号接触右括号意味着该文件中的信息将通过管道传输到这些行中。

我编译了一个仅供示例的读/写文件。下面是分为几个部分的文件,以解释每个部分的作用。

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

SRU 可以是本例中的任何内容。我们实际上将其设置为防止按 Enter 太快时发生崩溃。

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: 

现在,我们需要将变量写入文件。

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

我使用 .cdb 作为“命令数据库”的缩写形式。您可以使用任何扩展名。
下一部分是从头开始测试代码。我们不想使用在文件开头运行的设置变量,我们实际上希望它们从我们刚刚编写的 settings.cdb 加载。

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

因此,我们只是通过管道传送您在文件开头写入的前两行信息(您可以选择跳过设置要检查的行以确保其正常工作)来设置 input 和 input2 的变量。

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

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

这将显示在将 settings.cdb 通过管道传输到括号时设置的信息。作为额外的好工作激励因素,按 Enter 键并设置我们之前设置的默认值“1”将返回一条好工作消息。
使用支架管是双向的,并且比设置“FOR”的东西容易得多。 :)

Batch uses the less than and greater than brackets as input and output pipes.

>file.ext

Using only one output bracket like above will overwrite all the information in that file.

>>file.ext

Using the double right bracket will add the next line to the file.

(
echo
echo
)<file.ext

This will execute the parameters based on the lines of the file. In this case, we are using two lines that will be typed using "echo". The left bracket touching the right parenthesis bracket means that the information from that file will be piped into those lines.

I have compiled an example-only read/write file. Below is the file broken down into sections to explain what each part does.

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

SRU can be anything in this example. We're actually setting it to prevent a crash if you press Enter too fast.

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: 

Now, we need to write the variables to a file.

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

I use .cdb as a short form for "Command Database". You can use any extension.
The next section is to test the code from scratch. We don't want to use the set variables that were run at the beginning of the file, we actually want them to load FROM the settings.cdb we just wrote.

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

So, we just piped the first two lines of information that you wrote at the beginning of the file (which you have the option to skip setting the lines to check to make sure it's working) to set the variables of input and input2.

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

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

This displays the information that was set while settings.cdb was piped into the parenthesis. As an extra good-job motivator, pressing enter and setting the default values which we set earlier as "1" will return a good job message.
Using the bracket pipes goes both ways, and is much easier than setting the "FOR" stuff. :)

[旋木] 2024-09-07 09:17:59

所以你只需要这样做就对了?:

@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

So you just have to do this right?:

@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
寒江雪… 2024-09-07 09:17:59
:: 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 
gt;config.txt

ENDLOCAL
PAUSE
EXIT /B

输出:

$RunCount=1

$RunCount=2

$RunCount=3

上述技术也可用于在多个批处理文件之间共享变量。

来源:http://www.incodesystems.com/products/batchfi1.htm

:: 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 
gt;config.txt

ENDLOCAL
PAUSE
EXIT /B

Output:

$RunCount=1

$RunCount=2

$RunCount=3

The technique outlined above can also be used to share variables among multiple batch files.

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

堇年纸鸢 2024-09-07 09:17:59

有点老的主题,但几天前我有同样的问题,我想出了另一个想法(也许有人仍然会觉得它有用)

例如,你可以制作一个包含不同主题(家庭、大小、颜色、动物)的 config.bat 和在批处理脚本中以任何顺序单独应用它们:

@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

之后,您可以通过使用“call config.bat all”完全调用或仅调用其中的一部分来在任何地方使用它(请参见下面的示例)
这里的想法是,有时当您可以选择不一次调用所有内容时会更方便。有些变量可能您还不想被调用,因此您可以稍后调用它们。

示例 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

希望它能帮助其他人在这里帮助我回答他们的问题。

上述内容的简短版本:

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

美好的一天。

Kinda old subject but I had same question a few days ago and I came up with another idea (maybe someone will still find it usefull)

For example you can make a config.bat with different subjects (family, size, color, animals) and apply them individually in any order anywhere you want in your batch scripts:

@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

After that, you can use it anywhere by calling fully with 'call config.bat all' or calling only parts of it (see example bellow)
The idea in here is that sometimes is more handy when you have the option not to call everything at once. Some variables maybe you don't want to be called yet so you can call them later.

Example 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

Hope it helps the way others help me in here with their answers.

A short version of the above:

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

Good day.

卸妝后依然美 2024-09-07 09:17:59

根据我的观点,最好的选择是拥有键/值对文件,因为它可以从其他脚本语言读取。

另一件事是我希望在值文件中有一个注释选项 - 这可以通过 for /f 命令中的 eol 选项轻松实现。

这是示例

值文件:

;;;;;; file with example values ;;;;;;;;

;; Will be processed by a .bat file
;; ';' can be used for commenting a line

First_Value=value001

;;Do not let spaces arround the equal sign
;; As this makes the processing much easier
;; and reliable

Second_Value=%First_Value%_test

;;as call set will be used in reading script
;; refering another variables will be possible.

Third_Value=Something

;;; end

读取脚本:

@echo off

:::::::::::::::::::::::::::::
set "VALUES_FILE=E:\scripts\example.values"
:::::::::::::::::::::::::::::

FOR /F "usebackq eol=; tokens=* delims=" %%# in (
    "%VALUES_FILE%"
) do (
    call set "%%#"
)

echo %First_Value% -- %Second_Value% -- %Third_Value%

The best option according to me is to have key/value pairs file as it could be read from other scripting languages.

Other thing is I would prefer to have an option for comments in the values file - which can be easy achieved with eol option in for /f command.

Here's the example

values file:

;;;;;; file with example values ;;;;;;;;

;; Will be processed by a .bat file
;; ';' can be used for commenting a line

First_Value=value001

;;Do not let spaces arround the equal sign
;; As this makes the processing much easier
;; and reliable

Second_Value=%First_Value%_test

;;as call set will be used in reading script
;; refering another variables will be possible.

Third_Value=Something

;;; end

Reading script:

@echo off

:::::::::::::::::::::::::::::
set "VALUES_FILE=E:\scripts\example.values"
:::::::::::::::::::::::::::::

FOR /F "usebackq eol=; tokens=* delims=" %%# in (
    "%VALUES_FILE%"
) do (
    call set "%%#"
)

echo %First_Value% -- %Second_Value% -- %Third_Value%
冰魂雪魄 2024-09-07 09:17:59

在尝试使用具有可执行配置的方法时
我注意到它可能有效也可能无效
取决于脚本中的调用位置:

call config.cmd

我知道它没有任何意义,但对我来说这是事实。
当“call config.cmd”位于顶部时
脚本中,它可以工作,但如果在脚本中进一步,它就不起作用。

通过不起作用,我的意思是变量没有在调用脚本中设置。

非常非常奇怪!!!!

While trying to use the method with excutable configuration
I noticed that it may work or may NOT work
depending on where in the script is located the call:

call config.cmd

I know it doesn't make any sens, but for me it's a fact.
When "call config.cmd" is located at the top of the
script, it works, but if further in the script it doesn't.

By doesn't work, I mean the variable are not set un the calling script.

Very very strange !!!!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文