Crontab выполняется в фоне и, основываясь на данных в так называемых cron-таблицах, запускает задания по расписанию.
Для того, чтобы просмотреть существующую таблицу заданий cron, воспользуйтесь такой командой:
$ crontab –l
При планировании запуска скрипта по расписанию crontab принимает данные о том, когда нужно выполнить задание, в таком формате:
минута, час, день месяца, месяц, день недели.
Например, если надо, чтобы некий скрипт с именем command выполнялся ежедневно в 10:30, этому будет соответствовать такая запись в таблице заданий:
30 10 * * * command
Здесь универсальный символ «*», использованный для полей, задающих день месяца, месяц и день недели, указывает на то, что cron должен выполнять команду каждый день каждого месяца в 10:30.
Если, например, надо, чтобы скрипт запускался в 4:30PM каждый понедельник, понадобится создать в таблице заданий такую запись:
30 16 * * 1 command
Нумерация дней недели начинается с 0, 0 означает воскресенье, 6 — субботу.
Вот ещё один пример. Здесь команда будет выполняться в 12 часов дня в первый день каждого месяца.
00 12 1 * * command
Нумерация месяцев начинается с 1.
Для того чтобы добавить запись в таблицу, нужно вызвать crontab с ключом -e:
crontab –e
Затем можно вводить команды формирования расписания:
30 10 * * * /home/likegeeks/Desktop/myscript
Благодаря этой команде скрипт будет вызываться ежедневно в 10:30.
Если вы столкнётесь с ошибкой «Resource temporarily unavailable», выполните нижеприведённую команду с правами root-пользователя:
$ rm -f /var/run/crond.pid
Организовать периодический запуск скриптов с использованием cron можно ещё проще, воспользовавшись несколькими специальными директориями:
/etc/cron.hourly
/etc/cron.daily
/etc/cron.weekly
/etc/cron.monthly
Если поместить файл скрипта в одну из них, это приведёт, соответственно, к его ежечасному, ежедневному, еженедельному или ежемесячному запуску.
Запуск скриптов при входе в систему и при запуске оболочки
Автоматизировать запуск скриптов можно, опираясь на различные события, такие, как вход пользователя в систему или запуск оболочки. Тут можно почитать о файлах, которые обрабатываются в подобных ситуациях. Например, это следующие файлы:
$HOME/.bash_profile
$HOME/.bash_login
$HOME/.profile
Для того, чтобы запускать скрипт при входе в систему, поместите его вызов в файл .bash_profile.
А как насчёт запуска скриптов при открытии терминала? Организовать это поможет файл .bashrc.
Итоги
Сегодня мы разобрали вопросы, касающиеся управления жизненным циклом сценариев, поговорили о том, как запускать скрипты в фоне, как планировать их выполнение по расписанию. В следующий раз читайте о функциях в bash-скриптах и о разработке библиотек.
Bash-скрипты, часть 6: функции и разработка библиотек
Занимаясь разработкой bash-скриптов, вы рано или поздно столкнётесь с тем, что вам периодически приходится использовать одни и те же фрагменты кода. Постоянно набирать их вручную скучно, а копирование и вставка — не наш метод. Как быть? Хорошо бы найти средство, которое позволяет один раз написать блок кода и, когда он понадобится снова, просто сослаться на него в скрипте.
Оболочка bash предоставляет такую возможность, позволяя создавать функции. Функции bash — это именованные блоки кода, которые можно повторно использовать в скриптах.
Объявление функций
Функцию можно объявить так:
functionName {
}
Или так:
functionName() {
}
Функцию можно вызвать без аргументов и с аргументами.
Использование функций
Напишем скрипт, содержащий объявление функции и использующий её:
#!/bin/bash
function myfunc {
echo "This is an example of using a function"
}
count=1
while [ $count -le 3 ]
do
myfunc
count=$(( $count + 1 ))
done
echo "This is the end of the loop"
myfunc
echo "End of the script"
Здесь создана функция с именем myfunc. Для вызова функции достаточно указать её имя.
Результаты вызова функции
Функцию можно вызывать столько раз, сколько нужно.
Обратите внимание на то, что попытавшись использовать функцию до её объявления, вы столкнётесь с ошибкой. Напишем демонстрирующий это скрипт:
#!/bin/bash
count=1
while [ $count -le 3 ]
do
myfunc
count=$(( $count + 1 ))
done
echo "This is the end of the loop"
function myfunc {
echo "This is an example of using a function"
}
echo "End of the script"
Как и ожидается, ничего хорошего после его запуска не произошло.
Попытка воспользоваться функцией до её объявления
Придумывая имена для функций, учитывайте то, что они должны быть уникальными, иначе проблем не избежать. Если вы переопределите ранее объявленную функцию, новая функция будет вызываться вместо старой без каких-либо уведомлений или сообщений об ошибках. Продемонстрируем это на примере:
#!/bin/bash
function myfunc {
echo "The first function definition"
}
myfunc
function myfunc {
echo "The second function definition"
}
myfunc
echo "End of the script"
Как видно, новая функция преспокойно затёрла старую.
Переопределение функции
Использование команды return
Команда return позволяет задавать возвращаемый функцией целочисленный код завершения. Есть два способа работы с тем, что является результатом вызова функции. Вот первый:
#!/bin/bash
function myfunc {
read -p "Enter a value: " value
echo "adding value"
return $(( $value + 10 ))
}
myfunc
echo "The new value is $?"
Команда echo вывела сумму введённого числа и числа 10.
Вывод значения, возвращаемого функцией
Функция myfunc добавляет 10 к числу, которое содержится в переменной $value, значение которой задаёт пользователь во время работы сценария. Затем она возвращает результат, используя команду return. То, что возвратила функция, выводится командой echo с использованием переменной $?.
Если вы выполните любую другую команду до извлечения из переменной $? значения, возвращённого функцией, это значение будет утеряно. Дело в том, что данная переменная хранит код возврата последней выполненной команды.
Учтите, что максимальное число, которое может вернуть команда return — 255. Если функция должна возвращать большее число или строку, понадобится другой подход.
Запись вывода функции в переменную
Ещё один способ возврата результатов работы функции заключается в записи данных, выводимых функцией, в переменную. Такой подход позволяет обойти ограничения команды return и возвращать из функции любые данные. Рассмотрим пример:
#!/bin/bash
function myfunc {
read -p "Enter a value: " value
echo $(( $value + 10 ))
}
result=$( myfunc)
echo "The value is $result"
Вот что получится после вызова данного скрипта.
Запись результатов работы функции в переменную
Аргументы функций
Функции bash можно воспринимать как небольшие фрагменты кода, которые позволяют экономить время и место, избавляя нас от необходимости постоянно вводить с клавиатуры или копировать одни и те же наборы команд. Однако, возможности функций гораздо шире. В частности, речь идёт о передаче им аргументов.
Функции могут использовать стандартные позиционные параметры, в которые записывается то, что передаётся им при вызове. Например, имя функции хранится в параметре $0, первый переданный ей аргумент — в $1, второй — в $2, и так далее. Количество переданных функции аргументов можно узнать, обратившись к переменной $#. Если вы знакомы с третьей частью этого цикла материалов, вы не можете не заметить, что всё это очень похоже на то, как скрипты обрабатывают переданные им параметры командной строки.
Аргументы передают функции, записывая их после её имени:
myfunc $val1 10 20
Вот пример, в котором функция вызывается с аргументами и занимается их обработкой:
#!/bin/bash
function addnum {
if [ $# -eq 0 ] || [ $# -gt 2 ]
then
echo -1
elif [ $# -eq 1 ]
then
echo $(( $1 + $1 ))
else
echo $(( $1 + $2 ))
fi
}
echo -n "Adding 10 and 15: "
value=$(addnum 10 15)
echo $value
echo -n "Adding one number: "
value=$(addnum 10)
echo $value
echo -n "Adding no numbers: "
value=$(addnum)
echo $value
echo -n "Adding three numbers: "
value=$(addnum 10 15 20)
echo $value
Запустим скрипт.
Вызов функции с аргументами
Функция addnum проверяет число переданных ей при вызове из скрипта аргументов. Если их нет, или их больше двух, функция возвращает значение -1. Если параметр всего один, она прибавляет его к нему самому и возвращает результат. Если параметров два, функция складывает их.
Обратите внимание на то, что функция не может напрямую работать с параметрами, которые переданы скрипту при его запуске из командной строки. Например, напишем такой сценарий:
#!/bin/bash
function myfunc {
echo $(( $1 + $2 ))
}
if [ $# -eq 2 ]
then
value=$( myfunc)
echo "The result is $value"
else
echo "Usage: myfunc a b"
fi
При его запуске, а точнее, при вызове объявленной в нём функции, будет выведено сообщение об ошибке.