У меня есть crontab, который работает следующим образом:
0 0 * * * /execute/shell/script.sh
0 0 * * * /execute/shell/script1.sh
0 0 * * * /execute/shell/script2.sh
И я хочу запускать каждый сценарий на другом экране. Но я хочу, чтобы этот экран оставался включенным, чтобы в любое время, когда я хочу увидеть прогресс одного из этих сценариев, я всегда могу просто сделать screen -d -r
, и он снова подключит экран для меня. чтобы увидеть прогресс.
Я уверен, что должен быть способ сделать это. но подобные вопросы, которые я нашел, не дали ответа.
Crontab запускает экран Как использовать crontab для запуска сеанса экрана?
Нужно ли вам на самом деле взаимодействовать с командами, или вы просто хотите посмотреть статус до того, как команды завершатся, а результаты будут отправлены вам по почте?
Я столкнулся с подобной "проблемой", когда я выполнял traceroute(8)
и mtr
изнутри cron, чтобы контролировать соединение, при этом mtr
выполнялся в для
-петли, чтобы обеспечить более точные измерения в заданном интервале (от 5 до 16). 67 минут (от 300 до 1000 циклов)), но весь скрипт был рассчитан на работу примерно в течение часа (чтобы я не получал спам по электронной почте), поэтому я хотел иметь возможность видеть состояние так, как оно происходит.
Способ, которым cron
работает, это создание временного файла в /tmp, и немедленный вызов unlink(2)
(но все равно сохранение файла открытым); в дальнейшем он используется для хранения результатов ваших сценариев до их завершения, и он отправляется вам по электронной почте. Поэтому вы можете использовать lsof -n -c cron
(и/или lsof -n | fgrep cron
), чтобы узнать количество открытых файлов, которые были удалены, а затем получить доступ к этим файлам через пространство имён /proc/$PID/fd/$FD
, чтобы увидеть результаты работы ваших сценариев, запущенных изнутри cron, без необходимости использования screen
.
Можно попробовать что-нибудь вроде этого:
cat /etc/cron.d/test
*/10 * * * * root screen -dmS script bash -c '/execute/shell/script.sh; exec bash'
*/10 * * * * root screen -dmS script1 bash -c '/execute/shell/script1.sh; exec bash'
*/10 * * * * root screen -dmS script2 bash -c '/execute/shell/script2.sh; exec bash'
Должно сработать, я думаю. Конечно, редактируйте время на все, что вам нужно.
Выше (ответ Ярослава Кучера) не сработает, потому что при втором вызове команды будут порождать новые сеансы экрана с теми же именами, что и предыдущие.
Если вы хотите, чтобы у вас всегда были одни и те же сеансы экрана для одних и тех же скриптов, то я бы сделал это немного более хитрым.
Я бы выполнял эти сессии в @reboot cron со скриптами, которые создают постоянный цикл типа
#!/bin/bash
while true; do
if [ -f /tmp/script1_enabled ]; then
script1_function_or_command
rm /tmp/script1_enabled
fi
sleep 60;
done
Который будет запускаться каждую минуту, проверяя наличие именованного файла в /tmp - если он существует, то запустите команду, иначе подождите еще минуту.
Вторая часть будет командами cron, которые создают эти файлы каждый день - работая как булевый флаг, чтобы инициировать вызов скрипта.
После того, как скрипт будет выполнен, файл будет удален. Таким образом, вы можете сохранить те же самые сессии для ваших скриптов, и все равно запускать их с интервалами по своему усмотрению
Если 60-секундная задержка в цикле слишком велика для вас (нет возможности точно запустить скрипт в заданное время с помощью этого метода, так как сон будет выполняться в непредсказуемое время), то вы можете настроить inotifywait watches и выполнить скрипты, как только файл будет создан.
cron будет выглядеть следующим образом:
@reboot screen -dmS script1 /usr/local/bin/script1_watcher
@reboot screen -dmS script2 /usr/local/bin/script2_watcher
0 0 * * * touch /tmp/script1_enabled
15 */4 * * * touch /tmp/script2_enabled