shell
Mergemaster tips and tricks!
При переходе с версии на версию FreeBSD самым неприятным этапом является обновление конфигурационных файлов. mergemaster отнимает массу времени и сил, требует аккуратности и внимательности. Это наверное один из самых неудобных инструментов FreeBSD!
Но на самом деле это не совсем так! Если внимательно изучить, как он работает и разобраться с его ключами, то можно значительно упростить себе жизнь. Не скажу, что обновление станет приятным, но уж оно точно перестанет быть такой головной болью.
› Continue reading
значение по умолчанию для переменной shell
Иногда нужно выставить значение по умолчанию для переменной, которую может указать/не указать пользователь в качестве аргумента при запуске. Для этого можно использовать вот такую конструкцию:
VALUE='' VALUE_DEFAULT='default' if [ -z $VALUE ]; then VALUE="$VALUE_DEFAULT" fi echo $VALUE
Из явных плюсов – ее читабельность, как всегда в ущерб краткости. Пробуем написать тоже самое, но короче:
VALUE='1' VALUE_DEFAULT='default' [ -z $VALUE ] && VALUE="$VALUE_DEFAULT" echo $VALUE
Получилось, но теперь понять конструкцию чуть сложнее. Пробуем сделать еще более короткий вариант:
VALUE=''
VALUE_DEFAULT='default'
VALUE=${VALUE:-$VALUE_DEFAULT}
echo $VALUE
Самый короткий вариант, но понятный только тем, кто внимательно прочитал man sh.
Вывод сообщения в stderr из shell скрипта
Очень полезная вещь – перенаправление потоков вывода. С ее помощью в shell скриптах можно сделать многое, в том числе и вывод сообщений в stderr. Пример простого скрипта ниже:
#/bin/sh
DEBUG=0
print_debug()
{
if [ "x$DEBUG" != "x0" ]; then
echo $* >&2
fi
}
print_debug hello world
Переменная DEBUG, если не равно 0, указывает, что нужно выводить сообщения в функции print_debug. Обычное echo выводи строку со всеми аргументами функции (переменная $*) в stdout, которые перенаправляется в stderr ( >&2 ).
Запись сообщений в syslog из shell скрипта
Логи в скриптах можно вести несколькими способами, один из самых простых – записывать новые сообщения в какой-то файл. Но мне такой подход кажется неправильным. В системе уже есть специальный инструмент для ведения логов syslog. Вот его и стоит использовать!
Для добавления сообщений в syslog есть утилита logger. В принципе может писать сообщения и в отдельный файл. Напишу небольшую функцию, которую можно будет добавлять в любой скрипт для ведения логов.
add_log_message ()
{
local logger='/usr/bin/logger'
local tag='My Script'
local port=514
local host=localhost
local facility='user'
local level='notice'
local message=$1
if [ -z $message ]; then
return 1
else
$logger -t "$tag" -p ${facility}.${level} -P $port -h $host "$message"
if [ "x$?" != "x0" ]; then
return 2
fi
fi
}
add_log_message 'Hello world'
Опция -t задает TAG, фактически TAG можно использовать для идентификации источника сообщения. Так же logger умеет отправлять сообщения syslog-у на другом сервер, т.е. легко можно организовать сбор всех типов логов на один сервер.
logger -P 514 -h logger.domain.ru 'Hello World'
По умолчанию logger пишет все сообщения в facility user с приоритетом notice, но это можно поменять используя ключ -p:
logger -p cron.warning 'Hello world'
mtree на страже вашей FreeBSD
К сожалению в любом программном обеспечение есть уязвимости и дыры, который могут использовать хакеры в свои целях. С момента выхода обновления или security патча до момента исправления в вашей ОС может пройти какое-то время, т.е. это потенциальная возможность получить управление ваши серверов для злоумышленника, который может оставить закладки для будущего использования даже после того, как вы все исправите. Например он может заменить файл su или sudo, даже ps вместе ls могут стать смертельно опасными! Для защиты нужно отслеживать состояние системных файлов (владельцы, права, размер, хеши и т.п.)!
Tripwire – достаточно сложный и тяжелый продукт, конечно можно поставить из портов, но в FreeBSD уже есть утилита, которая прекрасно справится с поставленной задачей. › Continue reading
Генерация случайного числа в sh
Для Linux проблема получения случайного числа в скрипте решается переменной $RANDOM, которая специфична для bash и ряда других оболочек. Для FreeBSD с sh все несколько сложнее. Есть несколько решений, например в awk есть функция rand(). Но работа с awk мне не понравилась, так что пойдем другим путем. Получилось так, что мне нужно было получить число из промежутка от 1 до 3. Эту задачу и будем решать:
get_random_number()
{
local upper=3
local lower=1
local random=`/usr/bin/head -n 1 /dev/random | cksum | cut -f1 -d" " | sed 's/^.*\([0-9]\).*/\1/'`
if [ $random -le $upper ] && [ $random -ge $lower ]; then
echo $random
return 0
else
get_random_number
fi
}
/dev/random генерирует для нас произвольные байты, далее подсчитывается их cksum, из него берем одну цифру. Если попадает в нужный диапазон – выходим, если нет запускаем функцию еще раз.