У меня есть командный файл, и я хочу включить внешний файл, содержащий некоторые переменные (например, переменные конфигурации). Является ли это возможным?
Ответы:
Примечание: я предполагаю, что командные файлы 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
в каждой строке. Кавычки здесь , чтобы избежать таких вещей , как <
, >
, &
, |
. Однако они сами сломаются, когда во входных данных будут использоваться кавычки. Также всегда нужно быть осторожным при дальнейшей обработке данных в переменных, хранящихся с такими символами.
Как правило, автоматическое экранирование произвольного ввода, чтобы не вызывать головной боли или проблем в пакетных файлах, мне кажется совершенно невозможным. По крайней мере, я пока не нашел способа это сделать. Конечно, с первым решением вы перекладываете эту ответственность на того, кто пишет файл конфигурации.
Если внешний файл конфигурации также является допустимым пакетным файлом, вы можете просто использовать:
call externalconfig.bat
внутри вашего скрипта. Попробуйте создать следующий a.bat:
@echo off
call b.bat
echo %MYVAR%
и b.bat:
set MYVAR=test
Запуск a.bat должен сгенерировать вывод:
test
call
, кстати, синхронный) он говорит, что «процесс не может получить доступ к файлу, потому что он используется» и не может быть вызван.
Пакетная обработка использует скобки «меньше» и «больше» в качестве входных и выходных каналов.
>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». :)
Так что тебе просто нужно сделать это правильно ?:
@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
:: 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
Довольно старая тема, но у меня был такой же вопрос несколько дней назад, и я придумал другую идею (возможно, кому-то она все еще будет полезна)
Например, вы можете создать 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
Добрый день.
Не забываем старые добрые параметры. При запуске файла * .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:\>
Пытаясь использовать метод с удобной конфигурацией, я заметил, что он может работать или НЕ работать в зависимости от того, где в скрипте находится вызов:
вызов config.cmd
Я знаю, что это не имеет никакого значения, но для меня это факт. Когда "call config.cmd" находится в верхней части скрипта, он работает, но если дальше в скрипте - нет.
Под не работает, я имею в виду, что переменная не установлена в вызывающем скрипте.
Очень очень странно !!!!