Если вы работали с syslog'ом, то знаете, что у него есть приложение logger, необходимое для логгирования каких-то действий от обычных пользователей. И если многие программы умеют работать с syslog'ом самостоятельно, то логгировать все действия пользователей — это не всегда простая задача.
Тем не менее, есть как минимум два способа это сделать с использованием bash.
Способ 1. Переменная PROMPT_COMMAND + logger.
В bash есть одна малоизвестная переменная с названием PROMPT_COMMAND, назначение которой — выполнение какой-то команды перед выводом приглашения, заданного переменной $PS1. В этой переменной можно задать скрипт, который будет выполняться перед каждым выводом приглашения для новой команды.
PROMPT_COMMAND="/sbin/userlog"
Вот пример скрипта (userlog)
LAST_COMMAND=`history 1`
logger -t USER_$USER "$LAST_COMMAND"
Желательно сразу запретить чтение скрипта обычным пользователям, но оставить права на выполнение.
После этого можно прописать переменную в файл ~/.profile, например, и запретить пользователю его изменять.
shebang указывать не нужно, потому что тогда для выполнения будет запускаться еще один экземпляр оболочки.
В чем плюсы такого способа?
1) Далеко не все знают о такой переменной, которая командой env, например, не показывается (хотя, возможно, в каких-то системах и показывается).
2) Можно централизованно собирать логи syslog и достаточно легко их анализировать по тэгу USER_$USER, если надо выяснить, какие команды конкретный пользователь выполнил, при этом будет указано время окончания работы команды, которое можно сравнить со временем нужного события, например, удаления общего документа или push'а в репозиторий (или еще чего-нибудь, не суть).
3) Достаточно просто включать для вновь создаваемых пользователей, достаточно добавить эту переменную в файл /etc/skel/.profile, тогда действия всех создаваемых пользователей будут автоматически логгироваться без каких-то дополнительных действий.
В чем минусы?
1) Запись о выполнении команды будет только после окончания работы команды.
2) Можно отключить логгирование таким образом, если переназначить переменную PROMPT_COMMAND (правда, только для текущего сеанса, при новых входах эта переменная будет снова установлена). Плюс использование других конфигурационных файлов bash (~/.bashrc, используемый при запуске экземпляра bash не в режиме login shell), в которых можно unset'ить переменную.
Способ 2. Скрипт-компаньон + logger.
Способ, применимый к запуску какого-то конкретного приложения.
Способ на основе известного со времен DOS'а принципа. Файл приложения переименовывается во что-нибудь наподобие program.bin и на его месте создается файл-скрипт с именем program, который логгирует запуск приложения, а потом запускает само приложение и передает ему параметры командной строки.
Пример скрипта
#!/bin/bash
COMMAND_LINE="$0 $@"
logger -t APPNAME_$USER "$COMMAND_LINE"
exec $0.bin $@
Какие тут есть особенности?
1) Обработка входного потока (stdin), если приложению передаются данные через поток (Лично мне это ни разу не пригодилось, поэтому спорный вопрос, нужно ли это).
2) При обновлении приложения при помощи пакетного менеджера скрипт-компаньон скорее всего будет переписан новой версией бинарного файла приложения.
Если у вас есть какие-то способы, позволяющие без дополнительных приложений логгировать работу пользователей минимальными усилиями, был бы признателен за указание их в комментариях.
Автор: 3vi1_0n3