用于设置变量的常用批处理文件

时间:2017-09-11 02:33:44

标签: batch-file

我正在处理多个批处理文件,我希望它们共享一些变量,因此我创建了一个包含所有这些设置的批处理文件SetupEnv

rem General setup
:: To pause or not after running a batch file
SET isPause = true

:: The directory where your source code is located
SET directory = D

:: The folders where your primary & secondary source code is located
:: I like to have two source code folders, if you don't then just have them pointing to the same folder
SET primary_source_code = \Dev\App
SET secondary_source_code = \Dev\App2

:::::::::::::::::::::::::::::::::::::::::::: XAMPP :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
rem If you're using XAMPP then set these up
:: Your destination folder
SET base_destination = C:\xampp\htdocs

:: The base url that is pointing to your destination folder (in most cases it's localhost)
SET base_url = http://10.0.2.65

:::::::::::::::::::::::::::::::::::::::::: Angular :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
rem If you're using angular set these up
:: The folder where you built code is copied
SET build_file = dist

从另一个批处理文件中我首先调用该文件:

::setup
call ../SetupEnv

echo %directory% dir
pause;

问题是,即使文件运行顺利,我可以在输出中看到正在设置的东西,但变量不会传到我调用它的文件中。因此,在该示例中,%directory%未被打印。

修改 我也尝试使用Joey's answer

::setup
for /f "delims=" %%x in (../SetupEnv.txt) do (set "%%x")

echo %directory% dir
pause

但那也不起作用且%directory%没有打印

2 个答案:

答案 0 :(得分:1)

call ed批处理文件中设置变量有效,只要您不在被调用的批处理文件中使用setlocal(当它返回时会有一个隐含的endlocal ,所以变量会丢失):

> type a.bat
set var=old
echo %var%
call b.bat
echo %var%

> type b.bat
set var=new

> a.bat

> set var=old

> echo old
old

> call b.bat

> set var=new

> echo new
new

>

对于替代for解决方案,我会稍微将其更改为:

for /f "delims=" %%a in ('type b.bat^|findstr /bic:"set "') do %%a

这只会"执行"行,以set开头(忽略大写),因此您可以在该文件中保留任何注释。

注意:... do set "%%a"会向该行添加另一个set(您已经在该文件中有一个),从而生成set "set var=value",您显然不想要这样做。

答案 1 :(得分:0)

也许为时已晚,但是。 我有一个加载程序脚本实现,用于以Windows Batch和Unix Bash Shell脚本之间的通用格式加载配置文件。

格式说明

# FORMAT:
#   [<attributes>] <variable>[:[<class_name>]]=<value>
#
# <attributes>:           Variable space separated attributes: export
# <variable>:             Variable name corresponding to the regex: [_a-zA-Z][_a-zA-Z0-9]*
# <class_name>:           class variant name: OSWIN | OSUNIX | BAT | SH
#   OSWIN:                Apply on Windows system including cygwin/mingw/msys subsystems.
#   OSUNIX:               Apply on Unix/Linux systems excluding cygwin/mingw/msys subsystems.
#   BAT:                  Apply on Windows system when this file has loaded from the Windows batch script loader.
#   SH:                   Apply on any system when this file has loaded from the Bash shell script loader.
#
# <value>:                Can start by the `"` quote character, but two quotes does remove only when exist on both ends of a value.
#

注意:export属性仅在Unix Shell解析器中具有含义。

配置文件示例

export PYTHON_EXE_PATH:OSWIN="c:/python/x86/38/python.exe"
export PYTHON_EXE_PATH:OSUNIX=python3

export PYTHONDONTWRITEBYTECODE=1

MY_SHELL_SCRIPT:BAT=blabla.bat
MY_SHELL_SCRIPT:SH=blabla.sh

用法示例

call load_config.bat . . myvars.vars

这将从myvars.vars文件生成myvars.vars.in并将其加载。

该脚本的确会在解析实例文件之前从模板文件生成实例配置文件。实施有点复杂,将来可能会更改:https://sourceforge.net/p/contools/contools/HEAD/tree/trunk/Scripts/Tools/std/load_config.bat https://sourceforge.net/p/contools/contools/HEAD/tree/trunk/Scripts/Tools/std/.load_config

注意

似乎在复制粘贴的代码中stackoverflow错误地处理了制表符(并丢失了其他字符,如\x01),因此如果您通过CTRL + C直接复制它,则下面的代码可能不起作用。使用上面的链接直接下载脚本。

旧的实现(例如)

@echo off

setlocal DISABLEDELAYEDEXPANSION

set "__CONFIG_IN_DIR=%~1"
set "__CONFIG_OUT_DIR=%~2"
set "__CONFIG_FILE=%~3"

if not defined __CONFIG_IN_DIR (
  echo.%~nx0: error: input config directory is not defined.
  exit /b 1
) >&2

if not defined __CONFIG_OUT_DIR (
  echo.%~nx0: error: output config directory is not defined.
  exit /b 2
) >&2

set "__CONFIG_IN_DIR=%__CONFIG_IN_DIR:\=/%"
set "__CONFIG_OUT_DIR=%__CONFIG_OUT_DIR:\=/%"

if "%__CONFIG_IN_DIR:~-1%" == "/" set "__CONFIG_IN_DIR=%__CONFIG_IN_DIR:~0,-1%"
if "%__CONFIG_OUT_DIR:~-1%" == "/" set "__CONFIG_OUT_DIR=%__CONFIG_OUT_DIR:~0,-1%"

if not exist "%__CONFIG_IN_DIR%\" (
  echo.%~nx0: error: input config directory does not exist: "%__CONFIG_IN_DIR%".
  exit /b 10
) >&2

if not exist "%__CONFIG_OUT_DIR%\" (
  echo.%~nx0: error: output config directory does not exist: "%__CONFIG_OUT_DIR%".
  exit /b 11
) >&2

if not exist "%__CONFIG_OUT_DIR%\%__CONFIG_FILE%" ^
if exist "%__CONFIG_IN_DIR%/%__CONFIG_FILE%.in" (
  echo."%__CONFIG_IN_DIR%/%__CONFIG_FILE%.in" -^> "%__CONFIG_OUT_DIR%/%__CONFIG_FILE%"
  type "%__CONFIG_IN_DIR:/=\%\%__CONFIG_FILE%.in" > "%__CONFIG_OUT_DIR%/%__CONFIG_FILE%"
)

rem load configuration files
if not exist "%__CONFIG_OUT_DIR%/%__CONFIG_FILE%" (
  echo.%~nx0: error: config file is not found: "%__CONFIG_OUT_DIR%/%__CONFIG_FILE%".
  exit /b 20
) >&2

for /F "usebackq eol=# tokens=* delims=" %%i in ("%__CONFIG_OUT_DIR%/%__CONFIG_FILE%") do (
  endlocal
  setlocal DISABLEDELAYEDEXPANSION
  for /F "eol=# tokens=1,* delims==" %%j in ("%%i") do (
    set "__VAR=%%j"
    set "__VALUE=%%k"
    call :PARSE_EXPR && (
      setlocal ENABLEDELAYEDEXPANSION
      for /F "tokens=1,* delims==" %%i in ("!__VAR!=!__VALUE!") do (
        endlocal
        endlocal
        set "%%i=%%j"
      )
      type nul>nul
    ) || endlocal
  )
)

exit /b 0

:PARSE_EXPR
if not defined __VAR exit /b 1

rem CAUTION:
rem Inplace trim of surrounded white spaces ONLY from left and right sequences as a whole for performance reasons.
rem

:TRIM_VAR_NAME
:TRIM_VAR_NAME_LEFT_LOOP
if not defined __VAR exit /b 1
if not ^%__VAR:~0,1%/ == ^ / if not ^%__VAR:~0,1%/ == ^ / goto TRIM_VAR_NAME_RIGHT_LOOP
set "__VAR=%__VAR:~1%"
goto TRIM_VAR_NAME_LEFT_LOOP

:TRIM_VAR_NAME_RIGHT_LOOP
if not ^%__VAR:~-1%/ == ^ / if not ^%__VAR:~-1%/ == ^   / goto TRIM_VAR_NAME_RIGHT_LOOP_END
set "__VAR=%__VAR:~0,-1%"
if not defined __VAR exit /b 1
goto TRIM_VAR_NAME_RIGHT_LOOP

:TRIM_VAR_NAME_RIGHT_LOOP_END

if not defined __VALUE exit /b 0

rem Replace a value quote characters by the \x01 character.
set "__VALUE=%__VALUE:"=%"

:TRIM_VAR_VALUE
setlocal DISABLEDELAYEDEXPANSION

:TRIM_VAR_VALUE_LEFT_LOOP
if not defined __VALUE exit /b 0
if not ^%__VALUE:~0,1%/ == ^ / if not ^%__VALUE:~0,1%/ == ^ / goto TRIM_VAR_VALUE_RIGHT_LOOP
set "__VALUE=%__VALUE:~1%"
goto TRIM_VAR_VALUE_LEFT_LOOP

:TRIM_VAR_VALUE_RIGHT_LOOP
if not ^%__VALUE:~-1%/ == ^ / if not ^%__VALUE:~-1%/ == ^   / goto TRIM_VAR_VALUE_RIGHT_LOOP_END
set "__VALUE=%__VALUE:~0,-1%"
if not defined __VALUE exit /b 0
goto TRIM_VAR_VALUE_RIGHT_LOOP

:TRIM_VAR_VALUE_RIGHT_LOOP_END
(
  endlocal
  set "__VALUE=%__VALUE%"
)

for /F "eol=     tokens=1,* delims=:" %%i in ("%__VAR%") do (
  set "__VAR=%%i"
  set "__PLATFORM=%%j"
)

if not defined __VAR exit /b 1

if defined __PLATFORM ^
if not "%__PLATFORM%" == "BAT" ^
if not "%__PLATFORM%" == "WIN" ^
if not "%__PLATFORM%" == "OSWIN" exit /b 1

for /F "eol=# tokens=1,* delims=     " %%i in ("%__VAR%") do (
  set "__ATTR=%%i"
  set "__VAR=%%j"
)

if not defined __VAR (
  set "__VAR=%__ATTR%"
  set "__ATTR="
)

if not defined __VAR exit /b 1

if ^/ == ^%__VALUE:~1,1%/ goto PREPARSE_VALUE
if not ^/ == ^%__VALUE:~0,1%/ goto PREPARSE_VALUE
if not ^/ == ^%__VALUE:~-1%/ goto PREPARSE_VALUE

:REMOVE_QUOTES
for /F "tokens=* delims=" %%i in ("%__VALUE:~1,-1%") do set "__VALUE=%%i"

if not defined __VALUE exit /b 0

goto PARSE_VALUE

:PREPARSE_VALUE
set __HAS_VALUE=0
for /F "eol=# tokens=* delims=" %%i in ("%__VALUE%") do set "__HAS_VALUE=1"

if %__HAS_VALUE% EQU 0 (
  set "__VALUE="
  exit /b 0
)

:PARSE_VALUE
rem recode quote and exclamation characters
set "__ESC__=^"
set __QUOT__=^"
set "__EXCL__=!"
set "__VALUE=%__VALUE:!=!__EXCL__!%"
set "__VALUE=%__VALUE:^=!__ESC__!%"
set "__VALUE=%__VALUE:=!__QUOT__!%"

exit /b 0