Пакетный файл включает внешний файл для переменных


98

У меня есть командный файл, и я хочу включить внешний файл, содержащий некоторые переменные (например, переменные конфигурации). Является ли это возможным?


Реализация шахты: stackoverflow.com/questions/46147450/…
Андри

Ответы:


133

Примечание: я предполагаю, что командные файлы Windows, поскольку большинство людей, кажется, не подозревают о существенных различиях и просто слепо вызывают все с серым текстом на черном фоне DOS. Тем не менее, первый вариант должен работать и в DOS.

Исполняемая конфигурация

Самый простой способ сделать это - просто поместить переменные в пакетный файл, каждая со своим собственным setоператором:

set var1=value1
set var2=value2
...

и в вашей основной партии:

call config.cmd

Конечно, это также позволяет создавать переменные условно или в зависимости от аспектов системы, поэтому он довольно универсален. Однако там может выполняться произвольный код, и в случае синтаксической ошибки ваш основной пакет также выйдет. В мире UNIX это довольно распространено, особенно для оболочек. И если задуматься, то autoexec.batничего другого.

Пары ключ / значение

Другой способ - это какие-то var=valueпары в файле конфигурации:

var1=value1
var2=value2
...

Затем вы можете использовать следующий фрагмент для их загрузки:

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

Здесь используется тот же трюк, что и раньше, а именно использование setв каждой строке. Кавычки здесь , чтобы избежать таких вещей , как <, >, &, |. Однако они сами сломаются, когда во входных данных будут использоваться кавычки. Также всегда нужно быть осторожным при дальнейшей обработке данных в переменных, хранящихся с такими символами.

Как правило, автоматическое экранирование произвольного ввода, чтобы не вызывать головной боли или проблем в пакетных файлах, мне кажется совершенно невозможным. По крайней мере, я пока не нашел способа это сделать. Конечно, с первым решением вы перекладываете эту ответственность на того, кто пишет файл конфигурации.


У меня это не сработало, не могли бы вы проверить: stackoverflow.com/questions/46147450/…
Naguib

35

Если внешний файл конфигурации также является допустимым пакетным файлом, вы можете просто использовать:

call externalconfig.bat

внутри вашего скрипта. Попробуйте создать следующий a.bat:

@echo off
call b.bat
echo %MYVAR%

и b.bat:

set MYVAR=test

Запуск a.bat должен сгенерировать вывод:

test

У меня это не сработало, не могли бы вы проверить: stackoverflow.com/questions/46147450/…
Naguib

При параллельном использовании конфигурационного файла в другом скрипте (вызов его с помощью call, кстати, синхронный) он говорит, что «процесс не может получить доступ к файлу, потому что он используется» и не может быть вызван.
domih

2

Пакетная обработка использует скобки «меньше» и «больше» в качестве входных и выходных каналов.

>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». :)


1

Так что тебе просто нужно сделать это правильно ?:

@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

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

Вывод:

$ RunCount = 1

$ RunCount = 2

$ RunCount = 3

Описанный выше метод также можно использовать для обмена переменными между несколькими пакетными файлами.

Источник: http://www.incodesystems.com/products/batchfi1.htm


0

Довольно старая тема, но у меня был такой же вопрос несколько дней назад, и я придумал другую идею (возможно, кому-то она все еще будет полезна)

Например, вы можете создать 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

Добрый день.


-2

Не забываем старые добрые параметры. При запуске файла * .bat или * .cmd вы можете добавить до девяти параметров после имени командного файла:

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

Пример сценария

Myscript.bat может выглядеть примерно так:

@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:\>

-3

Пытаясь использовать метод с удобной конфигурацией, я заметил, что он может работать или НЕ работать в зависимости от того, где в скрипте находится вызов:

вызов config.cmd

Я знаю, что это не имеет никакого значения, но для меня это факт. Когда "call config.cmd" находится в верхней части скрипта, он работает, но если дальше в скрипте - нет.

Под не работает, я имею в виду, что переменная не установлена ​​в вызывающем скрипте.

Очень очень странно !!!!

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.