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

171

У меня есть скрипт, который работает, когда я запускаю его из командной строки, но когда я планирую его с, 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, но я могу как мой пользователь. Чего мне не хватает, чтобы заставить это работать должным образом?

ProfessionalAmateur
источник

Ответы:

159

Добавьте, 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
жилль
источник
@Giles - Спасибо, у cronменя есть своя собственная PATHили я могу проверить моего пользователя PATH? Я настроил ssmtp, чтобы он имел собственный userи wheelразрешающий доступ, думая, что это позволит любому использовать его (включая cron). Если это поможет, я на CENTOS 6.2
ProfessionalAmateur
3
@ProfessionalAmateur Ваша проблема не в том, что вам не разрешено использовать ssmtp, а в том, что ваша работа cron не находит исполняемый файл, вызываемый, ssmtpпотому что его нет в вашем PATH. Нет такой вещи как «твой пользователь PATH»; это настройка для процесса, а не для пользователя. Вы можете установить путь для всех ваших заданий cron, поместив PATH=…строку в ваш crontab.
Жиль
Мне также пришлось добавить MAILTO='XXXX@gmail.com ', чтобы он работал вместе с настройкой PATH. Странно, но у меня это сработало.
Мак
Для ssmtp можно использовать; ´which ssmtp´ ...
Фредрик Гаусс
@FredrickGauss Сделать этоtype ssmtp
Жиль
20

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

cd "$(dirname "$0")";
Хьюго
источник
14

Чтобы ответить на вопрос 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
Брэм
источник
7

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

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

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

D_Bye
источник
3

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

jippie
источник
1

Рабочим каталогом по умолчанию для cronвыполнения задания обычно является домашний каталог /home/your-user-name.

Принятие @Kusalananda отличный комментарий.

Умные люди помогают другим
источник
1
Нет. Это зависит от того, где система хранит домашние каталоги. /homeдалеко от универсального.
Кусалананда
1
@Kusalananda Стандарт LSB говорит /home.
user259412
1
@peterh Хорошо, macOS использует /Usersи использует исторические Unices /usr, и даже в Linux домашний каталог системного пользователя может быть где-то в /varдругом месте или где- то еще.
Кусалананда
1
@Kusalananda Это правильно.
user259412
Спасибо, ты единственный, кто действительно ответил на этот вопрос :)
OwN
0

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

* * * * * echo $PATH > /tmp/lolcronjobs

В моем случае Ubuntu по умолчанию использует только то, /usr/bin:/binчто вызвало несколько проблем.

mschuett
источник