Intereting Posts
Резервное копирование на удаленном сервере в зашифрованной папке Благодаря автоматическому подключению Bluetooth к гарнитуре приемник A2DP недоступен Попытка использовать TLS SMTP против Exim, получив ошибку безопасности; что не так? Как позволить моей собственной программе открываться в заданном рабочем пространстве? как рассчитать не-файловую память под RHEL? Настройки Vim в редакторе ncftp Два IP-адреса на одном интерфейсе, узнайте, какой из них используется Не удается переключиться на консоль, используя собственное скомпилированное ядро Как удалить неизвестный файл, который не имеет соответствующих разрешений Apache mod-security дает «Загруженный PCRE не совпадает с скомпилированным!» Автоматически устанавливать атрибут append для вновь созданных файлов / папок? Переименовывать файлы, а не каталоги Передать пароль для 7zip Использование tar с поиском Как запустить мою программу C из любой точки системы (Ubuntu 10.10)?

Доступ к переменной по разделу из файла конфигурации

У меня есть один файл конфигурации с разделом данных, как указано ниже. Использование сценария оболочки для доступа к каждой переменной. Для этого я использую команду sed. Теперь я сталкиваюсь с одной проблемой, например, если я забуду настроить один пример переменной: name [APP1], он примет имя [APP2].
Файл конфигурации:

[APP1] name=Application1 StatusScript=/home/status_APP1.sh startScript=/home/start_APP1.sh stopScript=/home/stop_APP1.sh restartScript=/home/restart.APP1.sh [APP2] name=Application2 StatusScript=/home/status_APP2.sh startScript=/home/start_APP2.sh stopScript=/home/stop_APP2.sh restartScript=/home/restart.APP2.sh logdir=/log/APP2/ . . . . . [APPN] name=ApplicationN StatusScript=/home/status_APPN.sh startScript=/home/start_APPN.sh stopScript=/home/stop_APPN.sh restartScript=/home/restart.APPN.sh logdir=/log/APPN 

команда оболочки с использованием:

 sed -nr "/^\[APP1\]/ { :l /^name[ ]*=/ { s/.*=[ ]*//; p; q;}; n; bl;}" 

Есть ли способ решить эту проблему, если какая-то переменная не настроена в одном разделе через ноль или 0 в качестве значения переменной.

Вы можете создать функцию оболочки следующим образом:

 printSection() { section="$1" found=false while read line do [[ $found == false && "$line" != "[$section]" ]] && continue [[ $found == true && "${line:0:1}" = '[' ]] && break found=true echo "$line" done } 

Затем вы можете использовать printSection как команду и передать в раздел в качестве параметра, например:

 printSection APP2 

Чтобы получить ваш параметр, вы можете использовать гораздо более простой sed, например:

 printSection APP2 | sed -n 's/^name=//p' 

Это будет работать на stdin и писать на stdout. Поэтому, если ваш пример файла конфигурации был назван /etc/application.conf, и вы хотели сохранить имя APP2 в переменной app2name, вы могли бы написать так:

 app2name=$(printSection APP2 | sed -n 's/^name//p/' < /etc/applications.conf) 

Или вы можете встроить часть параметра в функцию и вообще пропустить sed, например так:

 printValue() { section="$1" param="$2" found=false while read line do [[ $found == false && "$line" != "[$section]" ]] && continue [[ $found == true && "${line:0:1}" = '[' ]] && break found=true [[ "${line%=*}" == "$param" ]] && { echo "${line#*=}"; break; } done } 

Тогда вы бы присваивали свою переменную следующим образом:

 app2name=$(printValue APP2 name < /etc/applications.conf) 

Разберите вашу конфигурацию в однозначный формат, а затем прочитайте ее в ассоциативный массив в недавнем выпуске bash :

 awk '/^\[/ { app=substr($0,2,length-2) } /=/ { print app "." $0 }' file.conf 

Это находит все заголовки разделов и устанавливает переменную awk app в их содержимое. Затем перед каждой следующей строкой ставится префикс с этим значением, за которым следует точка.

Это создаст вывод как

 APP1.name=Application1 APP1.StatusScript=/home/status_APP1.sh APP1.startScript=/home/start_APP1.sh APP1.stopScript=/home/stop_APP1.sh APP1.restartScript=/home/restart.APP1.sh APP2.name=Application2 APP2.StatusScript=/home/status_APP2.sh APP2.startScript=/home/start_APP2.sh APP2.stopScript=/home/stop_APP2.sh APP2.restartScript=/home/restart.APP2.sh APP2.logdir=/log/APP2/ 

Если в вашем APP2 отсутствует подраздел name , строка APP2.name не будет отображаться.

Затем прочитайте это в ассоциативный массив в bash :

 declare -A conf while IFS='=' read -r key value; do conf[$key]="$value" done < <(awk '/^\[/ { app=substr($0,2,length-2) } /=/ { print app "." $0 }' file.conf) 

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

 printf 'The stopScript for APPN is "%s"\n' "${conf[APPN.stopScript]}" 

Это вернется

 The stopScript for APPN is "/home/stop_APPN.sh" 

Запрос несуществующего значения приведет к пустой строке.


Команда awk также может быть заменена следующей командой sed :

 sed -n \ -e '/^\[/{s/[][]//g;h;}' \ -e '/=/{H;g;s/\n/./;p;s/\..*//;h;}' file.conf 

Расширено и аннотировано:

 /^\[/{ # handle section headers s/[][]//g; # remove [ and ] h; # put into the hold-space } /=/{ # handle settings H; # append the line to the hold-space with newline as delimiter g; # get the hold-space s/\n/./; # replace the newline with a dot p; # output s/\..*//; # remove everything after the dot h; # put back into the hold-space }