【问题标题】:Batch file include external file for variables批处理文件包括变量的外部文件
【发布时间】:2011-02-15 08:56:10
【问题描述】:

我有一个批处理文件,我想包含一个包含一些变量(比如配置变量)的外部文件。有可能吗?

【问题讨论】:

标签: batch-file transclusion


【解决方案1】:

注意:我假设 Windows 批处理文件,因为大多数人似乎没有意识到存在显着差异,只是盲目地在黑色背景 DOS 上用灰色文本调用所有内容。不过,第一个变体应该也可以在 DOS 下工作。

可执行配置

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

set var1=value1
set var2=value2
...

在您的主要批次中:

call config.cmd

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

键/值对

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

var1=value1
var2=value2
...

然后您可以使用以下 sn-p 来加载它们:

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

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

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

【讨论】:

【解决方案2】:

如果外部配置文件也是有效的批处理文件,你可以直接使用:

call externalconfig.bat

在您的脚本中。尝试创建以下 a.bat:

@echo off
call b.bat
echo %MYVAR%

和 b.bat:

set MYVAR=test

运行 a.bat 应该会产生输出:

test

【讨论】:

  • 这对我不起作用,请检查一下:stackoverflow.com/questions/46147450/…
  • 如果在另一个脚本中并行使用配置文件(使用call 调用它,顺便说一句是同步的),它会说“进程无法访问该文件,因为它正在被使用”并且可以'不被调用。
  • @domih 你确定“通话”是同步的吗?我只为第二次脚本运行提供了正确的变量。
  • 嗯,问题出在 if...else 对我来说。
【解决方案3】:

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 输入括号时设置的信息。作为一个额外的好工作激励因素,按下回车键并设置我们之前设置为“1”的默认值将返回一个好工作消息。 使用支架管道是双向的,并且比设置“FOR”的东西要容易得多。 :)

【讨论】:

    【解决方案4】:

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

    @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
    

    【讨论】:

      【解决方案5】:
      :: 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
      

      输出:

      $RunCount=1

      $RunCount=2

      $RunCount=3

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

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

      【讨论】:

        【解决方案6】:

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

        例如,您可以制作一个包含不同主题(家庭、大小、颜色、动物)的 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
        

        美好的一天。

        【讨论】:

          【解决方案7】:

          在我看来,最好的选择是拥有键/值对文件,因为它可以从其他脚本语言中读取。

          另外,我希望在值文件中有一个 cmets 选项 - 这可以通过 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%
          

          【讨论】:

            【解决方案8】:

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

            调用 config.cmd

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

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

            非常非常奇怪!!!!

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2018-03-25
              • 2010-10-23
              • 2018-01-14
              • 1970-01-01
              • 2021-03-06
              • 1970-01-01
              相关资源
              最近更新 更多