Прочитайте файл конфигурации в BASH без использования " source"

Я пытаюсь прочитать файл конфигурации, который отформатирован следующим образом:

USER = username
TARGET = arrows

Я понимаю, что если бы я избавился от пробелов, я мог бы просто источник файла конфигурации, но по соображениям безопасности я пытаюсь избежать этого. Я знаю, что есть способ прочитать файл конфигурации строка за строкой. Я думаю, что процесс Что-то вроде:

  1. считывание строк в массив
  2. отфильтровать все строки, которые начинаются с #
  3. поиск имен переменных в массиве

после этого я потерял. Любая помощь будет очень признательна. Я пробовал что-то подобное без успеха:

backup2.config>cat ~/1

grep '^[^#].*' | while read one two;do
    echo $two
done

я вытащил это из сообщения форума, которое я нашел, просто не уверен, как изменить его в соответствии с моими потребностями, так как я так новичок в скриптах оболочки.

http://www.linuxquestions.org/questions/programming-9/bash-shell-program-read-a-configuration-file-276852/


будет чтобы автоматически назначить переменную, выполнив цикл через оба массива?

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