Проблема: При запуске «долгоиграющих» команд в консоли благополучно забываешь о них, переключаясь на другие задачи. Нужна нотификация окончания таких команд, дабы экономить время.
Решение: Для начала, сделаем хорошо нашему .bashrc и нам - вынесем все что касается приглашения коммандной строки в отдельный файл .bash_prompt, а в .bashrc оставим:
if [ -f ~/.bash_prompt ]; then
. ~/.bash_prompt
fi
Чтобы отслеживать продолжительности комманды, очевидно, необходимо записать время начала команды и ее окончание. К сожалению, прямого пути здесь нет. Сценарий будет следующим:- Записываем время команды в файлик.
- По окончании выполнения команды - сравниваем текущее время и записанное.
- Если времени много - нофицируем пользователя, что команда закончилась.
Запись времени команды в файлик
Как мы знаем, в bash есть замечательная переменная окружения PROMPT_COMMAND, в которой записанная по имени функция будет вызываться каждый раз при выводе приглашения оболочки. Это было первое что мне пришло на ум - сохранять время в этой точке. Вторая мысль, которая пришла следом - куда сохранять: для каждого tty в отдельный файл. Таким образом, две команды из разных консолек не «пересекутся». Например это было бы примерно так:
command_prompt() {
FTTY=`tty | sed 's#/#_#g'`
now=`date '+%s'` # Текущее время
# do not overwrite until promt notifies and removes
if [ ! -f "/tmp/$FTTY" ]; then
echo $now > "/tmp/$FTTY"
fi
}
PROMPT_COMMAND=command_prompt
Записать, записали. Как видно, здесь стоит проверка существования файла со временем. Если же файл есть, значит команда уже была и мы можем прочитать его и проверить длительность.
LONG_TIMEOUT=60
command_prompt() {
FTTY=`tty | sed 's#/#_#g'`
now=`date '+%s'` # Текущее время
if [ -f "/tmp/$FTTY" ]; then
last_command_time=`cat "/tmp/$FTTY"`
if [ `expr $now - $last_command_time` -gt $LONG_TIMEOUT ]; then
notify_long_command `expr $now - $last_command_time`
fi
rm -f "/tmp/$FTTY"
fi
echo $now > "/tmp/$FTTY"
}
PROMPT_COMMAND=command_prompt
Осталось нотифицировать. За что мне понравился в свое время KDE, так это за маленькую удобную консольную утилитку kdialog. Незаменимая вещь для налаживания доброго диалога с пользователем. Она может показывать диалоги: - Текстовые (обычные, предупреждающие, извиняющиеся, ошибочные), как просто так и с кнопками да-нет-наверное (
kdialog --yesnocancel "Привет, наверное!") - Принимать ввод пользователя, простым текстовым полем, выпадающим списком, переключалками или чекбоксами, слайдер, календарь и даже цвет
- Выводить прогресс бар!
- запрашивать файловые вещи, путь файла, папки или URL (диалоги выбора файла)
- ну и определять заголовок диалога, переопределять тексты кнопок и сохранять выбор пользователя "не показывать мне больше"
notify_long_command() {
if which kdialog > /dev/null; then
kdialog --passivepopup "\"$1\" completes in `format_time $2`"
fi
}
--passivepopup позволяет «кинуть» нотификацию, как, например, при отвалившейся сети.
И вот тут, захотелось большего - знать конкретную команду, которая выполняется. И иметь, в конце концов, нотификацию вида "rm -rf / завершилась за 00:05:25". Но авто-переменной BASH с текущей командой нет. Максимум что удалось накопать - это переменная, в которой записано "bash" - это и правда текущая команда :)