Существуют некоторые тонкие различия хотя:
#!/bin/bash
eg=whatever
if [ $eg == what* ]; then # file glob test
echo '[]'
fi
if [[ $eg == what* ]]; then # pattern match test
echo "[[]]"
fi
Если нет файл, названный, "что [что-то]" в текущем каталоге, не передаст первый тест.
Для dpkg это можно сделать, добавив
status-logger "logger -t dpkg -p info"
в /etc/dpkg/dpkg.cfg . Поскольку apt-get вызывает dpkg, также регистрируются действия apt-get / apt. См. man logger
для настройки информации, записываемой в системный журнал.
Я использую эту доступную задачу для обновления конфигураций:
- name: dpkg syslog
lineinfile:
dest: /etc/dpkg/dpkg.cfg
line: 'status-logger "logger -t dpkg -p info"'
Если вы используете журнал systemd, удобно проверять журналы через
journalctl SYSLOG_IDENTIFIER=dpkg
Изменить место записи журнала dpkg можно с помощью параметра - log
. Это разрешает только имена файлов. DPKG был создан как простой и эффективный инструмент для управления пакетами, поэтому отсутствие регистратора, который усложняет работу, является плюсом. Самым простым способом будет запись в файл, а системный журнал будет читать из этого файла, как вы уже знаете.
Вы можете использовать status-fd
для отправки статуса в файловый дескриптор, например / dev / log
или status-logger
, чтобы иметь посредника, который отправляет записи в системный журнал.
Кажется, что status-logger
/ status-fd
не всегда имеют тот же вывод, что и файл журнала, указанный в директиве log
. И даже alternatives.log
жестко -закодированы в исходном коде dpkg, которые вы не можете изменить без перекомпиляции.
Поэтому я попытался заменить файлы журнала на fifo и загрузить содержимое журнала в journald. Благодаря гибкости systemd это можно сделать без дополнительных зависимостей.
Подготовьте сценарий bash по адресу /usr/local/libexec/fifo2journal
. Не забывайте chmod +x
. Этот сценарий эффективно cat
с жестко закодированным тайм-аутом -в 60 с. Если в стандартном вводе нет данных (или строки -подачи ), этот сценарий просто выводит часть строки, которую он прочитал, и завершает работу (для сохранения ресурса ).
#!/bin/bash
while :; do
if IFS= read -r -t 60; then
printf "%s\n" "$REPLY"
else
printf "%s" "$REPLY"
exit 0
fi
done
Подготовьте модули systemd. (активация сокета с помощью fifo в файловой системе)
а./etc/systemd/system/fifo2journal@.socket
[Unit]
Description=fifo at %f
[Socket]
ListenFIFO=%f
SocketMode=0660
[Install]
WantedBy=sockets.target
б./etc/systemd/system/fifo2journal@.service
[Unit]
Description=fifo to journal for %f
Requires=fifo2journal@%i.socket
[Service]
ExecStart=/usr/local/libexec/fifo2journal
StandardInput=socket
StandardOutput=journal
SyslogIdentifier=%f
SyslogFacility=user
Удалите существующие файлы журналов на диске (, сделайте резервную копию, если хотите ). Включите и запустите блок сокетов systemd.
systemctl daemon-reload
for FILEPATH in /var/log/dpkg.log /var/log/alternatives.log; do
rm -f "$FILEPATH"
UNIT_NAME=$(systemd-escape --template=fifo2journal@.socket --path "$FILEPATH")
systemctl enable "$UNIT_NAME"
systemctl start "$UNIT_NAME"
done
Теперь вы можете просмотреть журнал(journalctl -f -t /var/log/dpkg.log
)и попробовать написать в него(echo hello >/var/log/dpkg.log
).
logrotate будет рассматривать fifo как пустой журнал и ничего не делать.
Имейте в виду, что этот метод требует запуска systemd для активации сокета. Это может привести к неожиданным последствиям, если systemd не запущен и вы пытаетесь открыть (закрытый )fifo без O_NONBLOCK
, особенно если вы спасаете свои rootfs через chroot.
Существует потенциальная проблема, если вы обновляете systemd, а активация сокета по какой-либо причине не готова в течение 60 секунд, и любой поток, пытающийся открыть FIFO без O_NONBLOCK
, зависает. Я хочу, чтобы этого никогда не случилось.