У меня есть сценарий bash, который выглядит так:
#!/bin/sh
PID=`ps faux | grep libt | awk 'NR==2{print $2}'`
STATUS=`ps faux | grep libt | awk 'NR==2{print $1}'`
if [ "$STATUS" = "ec2-user" ]; then
echo "libt already killed"
else
sudo kill $PID
echo "libt was killed"
fi
sleep 5
cd /home/ec2-user/libt
sudo ./libt
Я сохранил этот файл как restart.sh, и когда я запускаю его как ./restart.sh, он делает то, что должен (убивает процесс libt и перезапускает его). Однако сейчас я пытаюсь автоматизировать процесс с помощью cron. Итак, я сделал задание cron, которое хочу запускать каждые 6 часов, и оно выглядит так:
0 */6 * * * /home/ec2-user/restart.sh
Когда я запускаю crontab -l, я вижу этот отпечаток и знаю, что он был добавлен правильно. Я должен упомянуть, что служба не может быть перезапущена (например, «служба ... перезапуск»), необходимо найти идентификатор процесса, убить его, а затем запустить сценарий запуска.
Я обнаружил, что это задание cron не работает, я захожу в систему и могу сказать, просматривая журналы, что перезагрузки не произошло. Что я делаю не так? Что я могу сделать для устранения неполадок?
Любой совет поможет, это моя первая работа в cron :) Спасибо!
Предположительно, вы намерены использовать эти строки, чтобы избежать совпадения grep
команда на выходе ps
:
PID=`ps faux | grep libt | awk 'NR==2{print $2}'`
STATUS=`ps faux | grep libt | awk 'NR==2{print $1}'`
Вы не можете гарантировать, что вторая строка будет той, которую вы хотите. Вы должны устранить grep
используя обычный прием:
ps faux | grep [l]ibt
заключив символ в квадратные скобки, grep
ищет "libt", но не буквальный "[l] ibt", потому что он интерпретирует символы в скобках как список.
Вам следует использовать $()
для подстановки команд вместо обратных кавычек. Они более читабельны и проще в использовании.
Вы также можете получить имя пользователя и PID, используя один вызов ps
снижает вероятность состояния гонки, но вам действительно не нужно имя пользователя, поскольку вы его уже знаете. Вам нужно только знать, запущен процесс или нет.
Однако возможности ложных срабатываний все же есть. Если можете, вам следует использовать pgrep
и pkill
.
#!/bin/sh
PID=$(pgrep -U ec2-user libt 2>/dev/null)
if [ $? = 0 ]
then
kill $PID
echo "libt was killed"
else
echo "libt already killed"
fi
sleep 5
/home/ec2-user/libt/libt
Посмотри пожалуйста Управление процессом Чтобы получить больше информации.
sudo
не будет работать в cron'е; он хочет запросить пароль, поскольку вы не сохраняете его файл семафора активным, когда вы выходите из системы. Рассмотрите возможность установки в root
crontab вместо вашего собственного.
Вы должны попробовать заменить все это на пс-наблюдатель или Монит довольно легко. Это решит ваши проблемы с crontab.
С другой стороны, похоже, что geekosaur, вероятно, на правильном пути. Если вы хотите сохранить существующий сценарий, перепишите его для запуска из корневого crontab. Если ему нужно что-то сделать от имени другого пользователя, используйте sudo или su как root для этого пользователя. Это должно обойти любую странность sudo, с которой вы можете столкнуться.
Мой голос за это определенно для мониторинга.
А также позволяет пользователю запускать /bin/kill
и libt
без пароля вам, вероятно, потребуется добавить visiblepw
к Defaults
раздел sudoers файл например
Defaults env_reset, visiblepw
и
#allow user to run kill with no password entry
user ALL=NOPASSWD: /bin/kill, /home/ec2-user/libt/libt