Прочитайте файл конфигурации в BASH без использования " source"
Я пытаюсь прочитать файл конфигурации, который отформатирован следующим образом:
USER = username
TARGET = arrows
Я понимаю, что если бы я избавился от пробелов, я мог бы просто источник файла конфигурации, но по соображениям безопасности я пытаюсь избежать этого. Я знаю, что есть способ прочитать файл конфигурации строка за строкой. Я думаю, что процесс Что-то вроде:
- считывание строк в массив
- отфильтровать все строки, которые начинаются с #
- поиск имен переменных в массиве
после этого я потерял. Любая помощь будет очень признательна. Я пробовал что-то подобное без успеха:
backup2.config>cat ~/1
grep '^[^#].*' | while read one two;do
echo $two
done
я вытащил это из сообщения форума, которое я нашел, просто не уверен, как изменить его в соответствии с моими потребностями, так как я так новичок в скриптах оболочки.
будет чтобы автоматически назначить переменную, выполнив цикл через оба массива?
for (( i = 0 ; i < ${#VALUE[@]} ; i++ ))
do
"${NAME[i]}"=VALUE[i]
done
echo $USER
такой, что вызов $USER выведет "username"? Приведенный выше код не работает, но я знаю, что решение похоже на это.
4 ответов
следующий скрипт повторяет каждую строку во входном файле (ВАР в моем случае) и соответствует ли шаблон=
. Если знак равенства найден, он будет использовать Расширения Параметр для разбора переменной имя С стоимостью. Затем он сохраняет каждую часть в своем собственном массиве,имя и стоимостью соответственно.
#!/bin/bash
i=0
while read line; do
if [[ "$line" =~ ^[^#]*= ]]; then
name[i]=${line%% =*}
value[i]=${line#*= }
((i++))
fi
done < vars
echo "total array elements: ${#name[@]}"
echo "name[0]: ${name[0]}"
echo "value[0]: ${value[0]}"
echo "name[1]: ${name[1]}"
echo "value[1]: ${value[1]}"
echo "name array: ${name[@]}"
echo "value array: ${value[@]}"
вход
$ cat vars
sdf
USER = username
TARGET = arrows
asdf
as23
выход
$ ./varscript
total array elements: 2
name[0]: USER
value[0]: username
name[1]: TARGET
value[1]: arrows
name array: USER TARGET
value array: username arrows
во-первых,USER
- это переменная среды, поэтому было бы лучше, если бы вы использовали что-то другое. Использование строчных или смешанных имен переменных case-это способ избежать конфликтов имен.
#!/bin/bash
configfile="/path/to/file"
shopt -s extglob
while IFS='= ' read lhs rhs
do
if [[ $lhs != *( )#* ]]
then
# you can test for variables to accept or other conditions here
declare $lhs=$rhs
fi
done < "$configfile"
это устанавливает vars в вашем файле на значение, связанное с ним.
echo "Username: $USER, Target: $TARGET"
выводит
Username: username, Target: arrows
у меня есть скрипт, который принимает только очень ограниченное количество настроек и обрабатывает их по одному, поэтому я адаптировал ответ SiegeX к белому списку настроек, которые меня волнуют, и действую на них, когда дело доходит до них.
Я также удалил требование для пробелов вокруг =
в пользу игнорирования любых, которые существуют с помощью на trim
функция из другого ответа.
function trim()
{
local var=;
var="${var#"${var%%[![:space:]]*}"}"; # remove leading whitespace characters
var="${var%"${var##*[![:space:]]}"}"; # remove trailing whitespace characters
echo -n "$var";
}
while read line; do
if [[ "$line" =~ ^[^#]*= ]]; then
setting_name=$(trim "${line%%=*}");
setting_value=$(trim "${line#*=}");
case "$setting_name" in
max_foos)
prune_foos $setting_value;
;;
max_bars)
prune_bars $setting_value;
;;
*)
echo "Unrecognised setting: $setting_name";
;;
esac;
fi
done <"$config_file";
Спасибо SiegeX. Я думаю, что более поздние обновления, которые вы упомянули, не отражают этот URL.
Я должен изменить регулярное выражение, чтобы удалить кавычки, чтобы заставить его работать. С кавычками возвращаемый массив пуст.
i=0
while read line; do
if [[ "$line" =~ ^[^#]*= ]]; then
name[i]=${line%% =*}
value[i]=${line##*= }
((i++))
fi
done < vars
еще лучше версия .
i=0
while read line; do
if [[ "$line" =~ ^[^#]*= ]]; then
name[i]=`echo $line | cut -d'=' -f 1`
value[i]=`echo $line | cut -d'=' -f 2`
((i++))
fi
done < vars
первая версия имеет проблемы, если в конфигурационном файле нет места до и после"=". Также, если значение отсутствует, я вижу, что имя и значение заполняются одинаково. Второй версия не имеет ни одного из них. Кроме того, он обрезает ненужные начальные и конечные пробелы.
эта версия считывает значения, которые могут оказать = в нем. Более ранняя версия расщепляется при первом появлении =.
i=0
while read line; do
if [[ "$line" =~ ^[^#]*= ]]; then
name[i]=`echo $line | cut -d'=' -f 1`
value[i]=`echo $line | cut -d'=' -f 2-`
((i++))
fi
done < vars