sh
Обработка сигналов в sh
Сигналы – один из способов взаимодействия между процессами. Отправив определенный сигнал, можно приостановить или возобновить работы приложения, завершить его или сделать с ним еще что-нибудь. Сигнал определяется номером, которому соответствие имя. Посмотрите man signal или наберите kill -l чтобы получить список сигналов.
В скриптах обработка сигналов может быть крайне полезна.
› 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.
Генерация случайного числа в 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, из него берем одну цифру. Если попадает в нужный диапазон – выходим, если нет запускаем функцию еще раз.