Intereting Posts

Что такое «рабочий каталог», когда cron выполняет задание?

У меня есть скрипт, который работает, когда я запускаю его из командной строки, но когда я планирую его с cron я получаю ошибки, которые не могут найти файлы или команды. Мой вопрос двоякий:

  1. Когда я планирую задание cron с использованием crontab -e , использует ли он мой идентификатор пользователя в качестве основы для его разрешений? Или он использует идентификатор пользователя cron определенного типа и связанные с ним разрешения?

  2. Когда запускается задание cron, каков рабочий каталог? Это каталог, в котором я указываю сценарий для запуска или другой каталог?

Вот моя работа cron:

 15 7 * * * /home/xxxx/Documents/Scripts/email_ip_script.sh 

Вот сценарий:

 vIP_ADDR="`curl automation.whatismyip.com/n09230945.asp`" echo "$vIP_ADDR" sed "s/IPADDR/$vIP_ADDR/g" template.txt > emailmsg.txt ssmtp XXXXX@gmail.com < emailmsg.txt 

Вот ошибки, которые я получаю, когда просматриваю mail сообщение, созданное cron :

 sed: can't read template.txt: No such file or directory /home/xxxx/Documents/Scripts/email_ip_script.sh: line 15: ssmtp: command not found 

Он не может найти template.txt но он находится в том же каталоге, что и скрипт. Он также не может запускать ssmtp , но я могу как мой пользователь. Что мне не хватает, чтобы заставить это работать правильно?

Добавьте cd /home/xxxx/Documents/Scripts/ если вы хотите, чтобы ваша работа выполнялась в этом каталоге. Нет причин, по которым cron изменился бы на этот конкретный каталог. Cron запускает ваши команды в вашем домашнем каталоге.

Что касается ssmtp , это может быть не в PATH умолчанию. Путь по умолчанию Cron зависит от реализации, поэтому проверьте свою справочную страницу, но, по всей вероятности, ssmtp находится в /usr/sbin который не входит в ваш PATH умолчанию, только root.

 PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin 15 7 * * * cd /home/xxxx/Documents/Scripts && ./email_ip_script.sh 

Чтобы ответить на вопрос 1: если вы запустите crontab -e качестве собственного пользователя, задания будут запланированы в crontab этого пользователя и, таким образом, будут выполняться с разрешениями этого пользователя.

Но вам нужно учитывать, что задания будут выполняться в неинтерактивной оболочке, что означает, что $ PATH может отличаться от того, который у вас есть при запуске скрипта из командной строки.

Лучше всегда использовать полные пути в сценариях, особенно если вы планируете планировать их через / cron и т. Д.

Я бы также рекомендовал использовать полные пути ко всем файлам, чтобы избежать проблем, которые вы видите.

Чтобы предотвратить условия гонки и другие проблемы безопасности, вы также должны использовать mktemp чтобы убедиться, что прочитанный вами файл не изменяется ничем, кроме вашего сценария.

Поэтому я бы сменил сценарий на что-то вроде:

 vIP_ADDR="`curl automation.whatismyip.com/n09230945.asp`" echo "$vIP_ADDR" mail_msg=`/bin/mktemp` /bin/sed "s/IPADDR/$vIP_ADDR/g" /home/xxxx/Documents/Scripts/template.txt > $mailmsg /path/to/ssmtp XXXXX@gmail.com < $mailmsg /bin/rm $mailmsg 

Если ваш cronjob является сценарием bash, следующее будет содержать CD в месте вашего скрипта (если вы используете абсолютный путь в определении cron):

 cd "$(dirname "$0")"; 

cron запускает запланированные задания каждого пользователя в качестве этого пользователя. Этого должно быть достаточно для того, чтобы мы выяснили, что он запускает ваши сценарии относительно вашего домашнего каталога.

Если вам нужно, чтобы он запускался из другого места, просто используйте cd в своем скрипте, чтобы перейти в это место.

Вероятно, ssmtp находится в PATH по умолчанию cron (он настроен на очень узкий дизайн на большинстве платформ). Вы можете указать полный путь к ssmtp в своем скрипте или указать явно PATH в: a) файле crontab, который будет доступен для всех ваших скриптов, или b) в каждом скрипте.

Посмотрите эту ветку, как легко найти среду cron, она намного меньше, чем вы привыкли в интерактивной оболочке. Лучше всего предположить, что ничто не было установлено и явно задало его самостоятельно.