You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ublinux-init/ublinux/rc.preinit.d/24-logging

342 lines
24 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#!/usr/bin/env bash
#
# Author: Dmitry Razumov <asmeron@ublinux.com>
# Copyright (c) 2021-2025 UBLinux <support@ublinux.com>
#
# Initial script for Linux UBLinux
# This script are launching before starting init from initrd script
# Current dir allways must be set to root (/)
# All system path must be relative, except initrd dirs
ENABLED=yes
[[ ${ENABLED} == "yes" ]] || exit 0
DEBUGMODE=no
PATH=.:/:/usr/bin:/usr/local/bin:/usr/local/sbin
[[ -d /usr/lib/ublinux ]] && { ROOTFS= ; CMD_CHROOT= ; } || { [[ -d /sysroot ]] && ROOTFS="/sysroot" || ROOTFS="."; CMD_CHROOT="chroot ${ROOTFS}"; }
SOURCE=${ROOTFS}/usr/lib/ublinux/functions; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null || exit 0
SOURCE=${ROOTFS}/usr/lib/ublinux/default; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null || exit 0
debug_mode "$0" "$@"
SYSCONF="${ROOTFS}${SYSCONF}"
SOURCE=${SYSCONF}/config; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null
SOURCE=${SYSCONF}/logging; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null
## Настройка мониторинга и сбора системных событий и записи их в журналы для аудита
## AUDITD=disable|no|none|off<-># Отключить все созданные правила из конфигурации
## AUDITD[<id_name>[:<status>]]=<rule>[#<description>]
## <id_name> # Уникальное имя правила
## <status> # Статус правила, модет принимать значения: отсутствовать,enable,disable
## Отстутствует # Правило выключено или только комментарий
## enable # Правило включено
## disable # Правило выключено
## <rule> # Правило, без использование символа #
## <description> # Описание правила, начинается с символа #
#AUDITD[comment_1]="#Global settings"
#AUDITD[conf-d:enable]="-D #Remove any existing rules"
#AUDITD[conf-b:enable]="-b 8192 #Buffer Size. Feel free to increase this if the machine panic's"
#AUDITD[conf-f:enable]="-f 1 #Failure Mode. Possible values: 0 (silent), 1 (printk, print a failure message), 2 (panic, halt the system)"
#AUDITD[conf-i:disable]="-i #Ignore errors. e.g. caused by users or files not found in the local environment"
#AUDITD[comment_1221]="#Self Auditing ---------------------------------------------------------------------"
#AUDITD[comment_32423]="#Audit the audit logs"
#AUDITD[comment_23423]="#Successful and unsuccessful attempts to read information from the audit records"
#AUDITD[fs_auditlog_1]="-w /var/log/audit/ -p wra -k auditlog"
#AUDITD[fs_auditlog_2:disable]="-w /var/audit/ -p wra -k auditlog"
#AUDITD[event_chmod]="-a always,exit -F arch=x86_64 -S chmod,fchmod,fchmodat -F key=event_chmod"
#AUDITD[passwd_changes]="-w /etc/passwd -p wa -k passwd_changes"
exec_auditd(){
[[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && COMMAND=$1 && shift
[[ -n ${COMMAND} ]] || COMMAND="set="
local PARAM="$@"
local SERVICE_AUDITD="auditd.service"
local FILE_PATTERN_AUDITD_CONF="${ROOTFS}/etc/audit/rules.d/00-ubconfig.rules"
local SEPARATE_RULES_NAME_COMMENT=": "
local PREFIX_RULES_DISABLE="## "
if [[ ${AUDITD} == @(enable|yes|on) ]]; then
# Только для init
[[ -n ${ROOTFS} ]] && [[ -f ${ROOTFS}/lib/systemd/system/${SERVICE_AUDITD} ]] && [[ ! -e ${ROOTFS}/etc/systemd/system/multi-user.target.wants/${SERVICE_AUDITD} ]] \
&& ln -sf /usr/lib/systemd/system/${SERVICE_AUDITD} ${ROOTFS}/etc/systemd/system/multi-user.target.wants/${SERVICE_AUDITD}
elif [[ ${AUDITD} == @(disable|no|none|off) ]]; then
rm -f "${FILE_PATTERN_AUDITD_CONF}"
[[ -n ${ROOTFS} ]] && [[ -e ${ROOTFS}/etc/systemd/system/multi-user.target.wants/${SERVICE_AUDITD} ]] && rm -f "${ROOTFS}/etc/systemd/system/multi-user.target.wants/${SERVICE_AUDITD}"
return 0
fi
[[ -d ${FILE_PATTERN_AUDITD_CONF%/*} ]] || mkdir -p ${FILE_PATTERN_AUDITD_CONF%/*}
[[ -f ${FILE_PATTERN_AUDITD_CONF} ]] || true > "${FILE_PATTERN_AUDITD_CONF}"
if [[ -n ${PARAM} && ! ${PARAM} =~ ^"AUDITD="('enable'|'yes'|'on')?$ ]]; then
local SOURCE_AUDITD_RULES="${PARAM}"
elif [[ -n ${PARAM} && ${PARAM} =~ ^"AUDITD="('disable'|'no'|'none'|'off')?$ ]]; then
return 0
else
# Полное перезаполнение правил из конфигурации
SOURCE_AUDITD_RULES=$(grep -E "^[[:blank:]]*AUDITD\[" ${SYSCONF}/logging 2>/dev/null)
true > "${FILE_PATTERN_AUDITD_CONF}"
fi
if [[ ${COMMAND} == @("set="|"set+="|"set++=") ]]; then
# т.к. важен порядок, то считываем последовательно из конфигурации
while IFS='=' read -u3 AUDITD_RULE_NAME AUDITD_RULE_VAR; do
[[ ${AUDITD_RULE_NAME} =~ ^[[:blank:]]*'AUDITD['([^:]+)':'?('enable'|'disable'|'yes'|'no'|'none'|'on'|'off')?']' ]] && AUDITD_RULE_NAME=${BASH_REMATCH[1]} && AUDITD_RULE_STATUS=${BASH_REMATCH[2]}
[[ ${AUDITD_RULE_NAME} == @("AUDITD"|"") ]] && return 0
[[ ${AUDITD_RULE_STATUS} == @(""|disable|no|none|off) ]] && AUDITD_RULE_STATUS="#" || AUDITD_RULE_STATUS=
[[ ${AUDITD_RULE_VAR} =~ ^[\"\']?([^#]*)'#'?([^\"]*)[\'\"]?$ ]] && AUDITD_RULE_VAR=${BASH_REMATCH[1]} && AUDITD_RULE_COMMENT=${BASH_REMATCH[2]}
[[ -n ${AUDITD_RULE_COMMENT} ]] && echo "${PREFIX_RULES_DISABLE}${AUDITD_RULE_NAME}${SEPARATE_RULES_NAME_COMMENT}${AUDITD_RULE_COMMENT}" >> "${FILE_PATTERN_AUDITD_CONF}" \
|| echo "${PREFIX_RULES_DISABLE}${AUDITD_RULE_NAME}" >> "${FILE_PATTERN_AUDITD_CONF}"
[[ -n ${AUDITD_RULE_VAR} ]] && echo "${AUDITD_RULE_STATUS}${AUDITD_RULE_VAR}" >> "${FILE_PATTERN_AUDITD_CONF}"
done 3<<<${SOURCE_AUDITD_RULES}
elif [[ ${COMMAND} == @("set-="|"set--="|"remove") ]]; then
[[ -f ${FILE_PATTERN_AUDITD_CONF} ]] && while IFS='=' read -u3 AUDITD_RULE_NAME AUDITD_RULE_VAR; do
[[ ${AUDITD_RULE_NAME} =~ ^[[:blank:]]*'AUDITD['([^:]+)':'?('enable'|'disable'|'yes'|'no'|'none'|'on'|'off')?']' ]] && AUDITD_RULE_NAME=${BASH_REMATCH[1]} && AUDITD_RULE_STATUS=${BASH_REMATCH[2]}
# Уазан параметр не массив: AUDITD=
[[ ${AUDITD_RULE_NAME} == @("AUDITD"|"") ]] && return 0
[[ ${AUDITD_RULE_STATUS} == @(""|disable|no|none|off) ]] && AUDITD_RULE_STATUS="#" || AUDITD_RULE_STATUS=
[[ ${AUDITD_RULE_VAR} =~ ^[\"\']?([^#]*)'#'?([^\"]*)[\'\"]?$ ]] && AUDITD_RULE_VAR=${BASH_REMATCH[1]} && AUDITD_RULE_COMMENT=${BASH_REMATCH[2]}
if [[ -n ${AUDITD_RULE_COMMENT} ]]; then
sed -E "/^$(ere_quote_sed "${PREFIX_RULES_DISABLE}${AUDITD_RULE_NAME}${SEPARATE_RULES_NAME_COMMENT}${AUDITD_RULE_COMMENT}")[[:blank:]]*$/d" -i "${FILE_PATTERN_AUDITD_CONF}"
else
sed -E "/^$(ere_quote_sed "${PREFIX_RULES_DISABLE}${AUDITD_RULE_NAME}")[[:blank:]]*$/d" -i "${FILE_PATTERN_AUDITD_CONF}"
fi
[[ -n ${AUDITD_RULE_VAR} ]] && sed -E "/^$(ere_quote_sed "${AUDITD_RULE_STATUS}${AUDITD_RULE_VAR}")[[:blank:]]*$/d" -i "${FILE_PATTERN_AUDITD_CONF}"
done 3<<<${SOURCE_AUDITD_RULES}
fi
}
exec_auditd_live(){
[[ -z ${ROOTFS} ]] || return 0
local SERVICE_AUDIT_RULES="audit-rules.service"
local SERVICE_AUDITD="auditd.service"
if [[ -n ${AUDITD} ]]; then
# Если получен параметр AUDITD на включение или выключение, не массив, то
if [[ ${AUDITD} == @(enable|yes|on) ]]; then
if [[ $(pgrep -fc "exec_auditd_live") == 1 ]]; then
sleep 5
if systemctl --quiet is-active ${SERVICE_AUDITD} 2>/dev/null; then
systemctl --quiet reset-failed ${SERVICE_AUDITD} 2>/dev/null
systemctl --quiet restart ${SERVICE_AUDITD} 2>/dev/null
fi
ubconfig --quiet --target system set [system] SERVICES_ENABLE++="${SERVICE_AUDITD}"
fi
elif [[ ${AUDITD} == @(disable|no|none|off) ]]; then
pkill ${SERVICE_AUDITD%%.*}
ubconfig --quiet --target system set [system] SERVICES_ENABLE--="${SERVICE_AUDITD}" 2>/dev/null
fi
fi
return 0
}
## Настройка журналов
## https://www.freedesktop.org/software/systemd/man/journald.conf.html
## JOURNALD[<var>]=<value>
## <var> # Имя переменной настройки журнала
## Storage # Указывает, где хранить журнал. Доступны следующие параметры:
## # "volatile" - Журнал хранится в оперативной памяти, т.е. в каталоге /run/log/journal
## # "persistent" - Данные хранятся на диске, т.е. в каталоге /var/log/journal
## # "auto" - используется по-умолчанию
## # "none" - Журнал не ведётся
## Compress # Пороговое значение данных для сжатия и записи в ФС. Может принимать yes, no, цифра. Суффиксы, такие как K, M и G
## SplitMode # Определяет, следует ли разделять файлы журнала для каждого пользователя: «uid» или «none»
## RateLimitIntervalSec # Настраивает ограничение скорости, которое применяется ко всем сообщениям, интервал времени применения =30
## RateLimitBurst # Настраивает ограничение скорости, которое применяется ко всем сообщениям, лимит сообщений =10000
## SystemMaxUse # Указывает максимальное дисковое пространство, которое может использовать журнал в постоянном хранилище
## SystemKeepFree # Указывает объем места, которое журнал должен оставить свободным при добавлении записей журнала в постоянное хранилище
## SystemMaxFileSize # Определяет, до какого размера могут вырасти отдельные файлы журнала в постоянном хранилище перед ротацией
## RuntimeMaxUse # Указывает максимальное дисковое пространство, которое можно использовать в энергозависимом хранилище (в файловой системе /run)
## RuntimeKeepFree # Указывает объем пространства, которое будет выделено для других целей при записи данных в энергозависимое хранилище (в файловой системе /run)
## RuntimeMaxFileSize # Указывает объем места, которое отдельный файл журнала может занимать в энергозависимом хранилище (в файловой системе /run) перед ротацией
## ForwardToConsole # Перенаправить журнал на консоль, yes|no
## TTYPath # Измените используемый консольный TTY, если используется ForwardToConsole=yes. По умолчанию /dev/console.
## MaxLevelConsole # Тип сообщений перенаправляемые в журнал, варианты: emerg|alert|crit|err|warning|notice|info|debug или целочисленные значения в диапазоне 07
## <value> # Значение переменной настройки журнала
#JOURNALD[Storage]=persistent
#JOURNALD[Compress]=yes
#JOURNALD[SystemMaxUse]=8M
#JOURNALD[RuntimeMaxUse]=8M
exec_journald(){
[[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && COMMAND=$1 && shift
[[ -n ${COMMAND} ]] || COMMAND="set="
FILE_JOURNALD_CONF="${ROOTFS}/etc/systemd/journald.conf.d/00-ubconfig.conf"
local PARAM="$@"
if [[ -n ${PARAM} ]]; then
local JOURNALD=
declare -A JOURNALD=()
[[ ${PARAM} =~ ^[[:alnum:]_]+("="|"[".*"]=") ]] && eval "${PARAM%%=*}=\${PARAM#*=}"
fi
[[ ! -f ${FILE_JOURNALD_CONF} ]] && mkdir -p "${FILE_JOURNALD_CONF%/*}" && touch ${FILE_JOURNALD_CONF}
[[ $(cat ${FILE_JOURNALD_CONF}) =~ "[Journal]" ]] || echo "[Journal]" > ${FILE_JOURNALD_CONF}
if [[ ${COMMAND} == @("set="|"set+="|"set++=") ]] && [[ ${#JOURNALD[@]} != 0 ]]; then
while IFS= read -u3 NAME_VAR; do
if [[ $(cat ${FILE_JOURNALD_CONF}) =~ "${NAME_VAR}=" ]]; then
sed "s/^${NAME_VAR}=.*/${NAME_VAR}=${JOURNALD[${NAME_VAR}]}/g" -i ${FILE_JOURNALD_CONF}
else
echo "${NAME_VAR}=${JOURNALD[${NAME_VAR}]}" >> ${FILE_JOURNALD_CONF}
fi
done 3< <(printf "%s\n" "${!JOURNALD[@]}")
elif [[ ${COMMAND} == @("set-="|"set--="|"remove") ]]; then
if [[ ${PARAM%%=*} =~ ^.*'['(.*)']' ]]; then
NAME_VAR=${BASH_REMATCH[1]}
sed "/${NAME_VAR}=/d" -i ${FILE_JOURNALD_CONF}
fi
fi
}
exec_journald_live(){
[[ -z ${ROOTFS} ]] || return 0
SERVICE_NAME="systemd-journald.service"
if [[ $(pgrep -fc "exec_journald_live") == 1 ]]; then
sleep 5
systemctl reset-failed ${SERVICE_NAME} 2>/dev/null
systemctl --quiet restart ${SERVICE_NAME} 2>/dev/null
fi
}
## Настройка дампа ядра
## https://www.freedesktop.org/software/systemd/man/latest/systemd-coredump.html
## SYSTEMD_COREDUMP[<var>]=<value>
## <var> # Имя переменной настройки журнала
## Storage # Указывает, где хранить дамп ядра. Доступны следующие параметры:
## journal # Дампы будут храниться в журнале и перезаписываться в соответствии со стандартными принципами ротации журналов
## external # Значение по умолчанию, дампы сохраняются в каталоге /var/lib/systemd/coredump/
## none # Дампы ядра записываются (включая обратную трассировку, если возможно), но не сохраняются
## Compress # Используется для сжатия дампов ядра. Принимает логический аргумент - *yes или no
## *yes # Дампы сжимаются при сохранении (значение по умолчанию)
## no # Дампы сохраняются без сжатия.
## ProcessSizeMax # Максимальный размер дампа процесса, который может быть сохранен. Если размер дампа превышает значение этого параметра, то дамп сохранен не будет. Суфиксы: B
## # Параметры Storage=none и ProcessSizeMax=0 отключает всю обработку дампа памяти, за исключением записи журнала
## ExternalSizeMax # Максимальный (сжатый или несжатый) размер дампа процесса, который будет сохранен на диске
## JournalSizeMax # Максимальный (сжатый или несжатый) размер дампа процесса, который будет сохранен в журнале системы
## MaxUse # Максимальный объем общего дискового пространства, который может быть использован для хранения дампов процессов. Суфиксы: B,K,M,G,T,P,E
## KeepFree # Минимальный объем свободного дискового пространства, который должен оставаться на диске при хранении дампов. Суфиксы: B,K,M,G,T,P,E
## <value> # Значение переменной настройки журнала
#SYSTEMD_COREDUMP[Storage]=none
#SYSTEMD_COREDUMP[ProcessSizeMax]=0
exec_systemd_coredump(){
[[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && COMMAND=$1 && shift
[[ -n ${COMMAND} ]] || COMMAND="set="
FILE_SYSTEMD_COREDUMP_CONF="${ROOTFS}/etc/systemd/coredump.conf.d/00-ubconfig.conf"
local PARAM="$@"
if [[ -n ${PARAM} ]]; then
local SYSTEMD_COREDUMP=
declare -A SYSTEMD_COREDUMP=()
[[ ${PARAM} =~ ^[[:alnum:]_]+("="|"[".*"]=") ]] && eval "${PARAM%%=*}=\${PARAM#*=}"
fi
[[ ! -f ${FILE_SYSTEMD_COREDUMP_CONF} ]] && mkdir -p "${FILE_SYSTEMD_COREDUMP_CONF%/*}" && touch ${FILE_SYSTEMD_COREDUMP_CONF}
[[ $(cat ${FILE_SYSTEMD_COREDUMP_CONF}) =~ "[Coredump]" ]] || echo "[Coredump]" > ${FILE_SYSTEMD_COREDUMP_CONF}
if [[ ${COMMAND} == @("set="|"set+="|"set++=") ]] && [[ ${#SYSTEMD_COREDUMP[@]} != 0 ]]; then
while IFS= read -u3 NAME_VAR; do
if [[ $(cat ${FILE_SYSTEMD_COREDUMP_CONF}) =~ "${NAME_VAR}=" ]]; then
sed "s/^${NAME_VAR}=.*/${NAME_VAR}=${SYSTEMD_COREDUMP[${NAME_VAR}]}/g" -i ${FILE_SYSTEMD_COREDUMP_CONF}
else
echo "${NAME_VAR}=${SYSTEMD_COREDUMP[${NAME_VAR}]}" >> ${FILE_SYSTEMD_COREDUMP_CONF}
fi
done 3< <(printf "%s\n" "${!SYSTEMD_COREDUMP[@]}")
elif [[ ${COMMAND} == @("set-="|"set--="|"remove") ]]; then
if [[ ${PARAM%%=*} =~ ^.*'['(.*)']' ]]; then
NAME_VAR=${BASH_REMATCH[1]}
sed "/${NAME_VAR}=/d" -i ${FILE_SYSTEMD_COREDUMP_CONF}
fi
fi
}
## Настройка ротации файлов логов утилитой logrotate
## https://man.archlinux.org/man/logrotate.conf.5
## LOGROTATE[<tag>]="<mask_file_1>,<mask_file_2>,<mask_file_n>:<setting_1>,<setting_2>,<setting_n>"
#LOGROTATE[samba]="/var/log/samba/log.smbd,/var/log/samba/log.nmbd,/var/log/samba/*.log:notifempty,missingok,copytruncate"
#LOGROTATE[chrony]="/var/log/chrony/*.log:missingok,nocreate,sharedscripts,postrotate,/usr/bin/chronyc cyclelogs > /dev/null 2>&1 || true,endscript"
#LOGROTATE[clamav]="/var/log/clamav/clamd.log,/var/log/clamav/freshclam.log,/var/log/clamav/clamav-milter.log:create 644 clamav clamav,sharedscripts,missingok,notifempty,postrotate,/bin/kill -HUP \`cat /run/clamav/clamd.pid 2>/dev/null\` 2> /dev/null || true,/bin/kill -HUP \`cat /run/clamav/freshclam.pid 2>/dev/null\` 2> /dev/null || true,/bin/kill -HUP \`cat /run/clamav/clamav-milter.pid 2>/dev/null\` 2> /dev/null || true,endscript"
exec_logrotate(){
[[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && COMMAND=$1 && shift
[[ -n ${COMMAND} ]] || COMMAND="set="
FILE_PATTERN_LOGROTATE_CONF="${ROOTFS}/etc/logrotate.d/ubconfig-"
local PARAM="$@"
if [[ -n ${PARAM} ]]; then
local LOGROTATE=
declare -A LOGROTATE=()
[[ ${PARAM} =~ ^[[:alnum:]_]+("="|"[".*"]=") ]] && eval "${PARAM%%=*}=\${PARAM#*=}"
fi
[[ -d ${FILE_PATTERN_LOGROTATE_CONF%/*} ]] || mkdir -p ${PATH_LOGROTATE_CONF%/*}
if [[ ${COMMAND} == "set=" ]] && [[ ${#LOGROTATE[@]} != 0 ]]; then
while IFS= read -u3 NAME_FILE; do
FILES_LOG="${LOGROTATE[${NAME_FILE}]%%:*}"; FILES_LOG="${FILES_LOG//,/ }"
RULES_LOG="${LOGROTATE[${NAME_FILE}]#*:}"
TAB_COUNT='\t'
# Вставляем список файлов логов
echo "${FILES_LOG} {" > "${FILE_PATTERN_LOGROTATE_CONF}${NAME_FILE}"
# Вставляем правила для вращения логов
while IFS= read -r SELECT_RULES_LOG; do
[[ ${SELECT_RULES_LOG} == "endscript" ]] && TAB_COUNT='\t'
echo -e "${TAB_COUNT}${SELECT_RULES_LOG}" >> "${FILE_PATTERN_LOGROTATE_CONF}${NAME_FILE}"
[[ ${SELECT_RULES_LOG} == "postrotate" ]] && TAB_COUNT='\t\t'
done < <(tr ',' '\n' <<< ${RULES_LOG})
echo "}" >> "${FILE_PATTERN_LOGROTATE_CONF}${NAME_FILE}"
done 3< <(printf "%s\n" "${!LOGROTATE[@]}")
elif [[ ${COMMAND} == @("set+="|"set++=") ]] && [[ ${#LOGROTATE[@]} != 0 ]]; then
while IFS= read -u3 NAME_FILE; do
[[ -f ${FILE_PATTERN_LOGROTATE_CONF}${NAME_FILE} ]] || return 0
FILES_LOG="${LOGROTATE[${NAME_FILE}]%%:*}"
RULES_LOG="${LOGROTATE[${NAME_FILE}]#*:}"
[[ ${FILES_LOG} == ${RULES_LOG} ]] && unset RULES_LOG
FILES_LOG="${FILES_LOG//,/ }"
# Вставить в список файлов последним
[[ -n ${FILES_LOG} ]] && ESC_FILES_LOG=$(sed 's/[^a-zA-Z0-9=",_@#%&<> -]/\\&/g' <<< "${FILES_LOG}")
[[ -n ${FILES_LOG} ]] && [[ ! $(cat "${FILE_PATTERN_LOGROTATE_CONF}${NAME_FILE}") =~ ${FILES_LOG} ]] \
&& sed -E "0,/ \{/s/ \{/ ${ESC_FILES_LOG} \{/" -i "${FILE_PATTERN_LOGROTATE_CONF}${NAME_FILE}"
# Вставить в список правил последним
[[ -n ${RULES_LOG} ]] && ESC_RULES_LOG=$(sed 's/[^a-zA-Z0-9=",_@#%&<> -]/\\&/g' <<< "${RULES_LOG}")
[[ -n ${RULES_LOG} ]] && [[ ! $(cat "${FILE_PATTERN_LOGROTATE_CONF}${NAME_FILE}") =~ ${RULES_LOG} ]] \
&& sed -E "/^\}$/i\\\t${ESC_RULES_LOG}" -i "${FILE_PATTERN_LOGROTATE_CONF}${NAME_FILE}"
done 3< <(printf "%s\n" "${!LOGROTATE[@]}")
elif [[ ${COMMAND} == @("set-="|"set--=") ]]; then
while IFS= read -u3 NAME_FILE; do
FILES_LOG="${LOGROTATE[${NAME_FILE}]%%:*}"
RULES_LOG="${LOGROTATE[${NAME_FILE}]#*:}"
[[ ${FILES_LOG} == ${RULES_LOG} ]] && unset RULES_LOG
FILES_LOG="${FILES_LOG//,/ }"
# Если удаляемая часть относится к файлу, то просто вырезать, если к тексту, то удалить строку
[[ -n ${FILES_LOG} ]] && ESC_FILES_LOG=$(sed 's/[^a-zA-Z0-9=",_@#%&<> -]/\\&/g' <<< "${FILES_LOG}")
[[ -n ${FILES_LOG} ]] && [[ $(cat "${FILE_PATTERN_LOGROTATE_CONF}${NAME_FILE}") =~ ${FILES_LOG} ]] \
&& sed -E "0,/ \{/s/${ESC_FILES_LOG}//" -i "${FILE_PATTERN_LOGROTATE_CONF}${NAME_FILE}"
[[ -n ${RULES_LOG} ]] && ESC_RULES_LOG=$(sed 's/[^a-zA-Z0-9=",_@#%&<> -]/\\&/g' <<< "${RULES_LOG}")
[[ -n ${RULES_LOG} ]] && [[ $(cat "${FILE_PATTERN_LOGROTATE_CONF}${NAME_FILE}") =~ ${RULES_LOG} ]] \
&& sed "/${ESC_RULES_LOG}/d" -i "${FILE_PATTERN_LOGROTATE_CONF}${NAME_FILE}"
done 3< <(printf "%s\n" "${!LOGROTATE[@]}")
elif [[ ${COMMAND} == "remove" ]]; then
while IFS= read -u3 NAME_FILE; do
[[ -f ${FILE_PATTERN_LOGROTATE_CONF}${NAME_FILE} ]] || return 0
rm -f "${FILE_PATTERN_LOGROTATE_CONF}${NAME_FILE}"
done 3< <(printf "%s\n" "${!LOGROTATE[@]}")
fi
}
# Применить ротцию принудительно на указанный файл
# $1 # Имя переменной с файлом, пример: LOGROTATE[clamav]
exec_logrotate_live(){
[[ -z ${ROOTFS} ]] || return 0
NAME_FILE=$1
[[ ${NAME_FILE%%=*} =~ ^.*'['(.*)']' ]] && NAME_FILE=${BASH_REMATCH[1]}
[[ -n ${NAME_FILE} ]] || return 0
FILE_PATTERN_LOGROTATE_CONF="${ROOTFS}/etc/logrotate.d/ubconfig-"
if [[ $(pgrep -fc "exec_logrotate_live") == 1 ]]; then
sleep 2
logrotate -f "${FILE_PATTERN_LOGROTATE_CONF}${NAME_FILE}"
fi
}
################
##### MAIN #####
################
# Если файл подключен как ресурс с функциями, то выйти
return 0 2>/dev/null && return 0
if [[ -z $@ ]]; then
while read -r FUNCTION; do
$"${FUNCTION##* }"
done < <(declare -F | grep "declare -f exec_")
else
FUNCTION=
while [[ $# -gt 0 ]]; do
[[ -z ${1} ]] || { declare -f "${1}" &>/dev/null && FUNCTION+="; ${1}" || FUNCTION+=" '${1//\'/}'"; }
shift
done
eval ${FUNCTION#*; }
fi