Вопрос или проблема
У меня есть .sh
скрипт, который создает .tar.gz
файл и передает его на удаленный сервер с использованием RSA
ключей для аутентификации.
Скрипт запускается из терминала
, но не работает, когда я пытаюсь настроить его как Cron
задачу.
Я получаю электронное письмо от Cron Daemon
, в котором говорится о сбое: “/bin/sh: /home/backup.sh: Permission denied
“, и файл не передается на другой сервер.
Я установил наиболее вероятную причину из этого поста на askubuntu, что это, скорее всего, связано с тем, что “Cron
” передает минимальный набор переменных окружения для ваших задач.
Решение, похоже, заключается в том, чтобы включить
#!/bin/bash
PATH=/opt/someApp/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# остальная часть скрипта
Любая помощь с настройкой этого будет очень полезна.
Я использую Ubuntu Server 11.04
ИЗМЕНЕНИЕ: ls -la backup.sh
выдает
-rw-r--r-- 1 root root 1053 2012-10-13 15:08 backup.sh
Спасибо за вывод ls
. Похоже, что жалоба cron о том, что файл не имеет правильных разрешений, может быть воспринята дословно (в частности, ему не хватает разрешений на выполнение); попробуйте выполнить chmod 755 ./home/backup.sh
и посмотрите, поможет ли это.
Изменение: Я рад, что мы это выяснили. Вам сначала нужно посмотреть, какой пользователь запускает эту задачу через cron, и проверить владельца директории backupdir. Пользователь должен иметь разрешение на запись в этой директории; слепое изменение разрешений chmod
не поможет.
Сообщение “Permission denied” похоже указывает на то, что пользователь, от имени которого cron выполняет скрипт, не имеет подходящих разрешений для доступа к скрипту /home/backup.sh
.
Проверьте, что у пользователя, чей crontab используется, есть как минимум r-x
на /home и на backup.sh.
Вы можете установить любые переменные окружения в crontab. Один из способов – добавить строку в файл crontab в следующем формате:
varname=value
Эта переменная окружения будет установлена для всех cron задач, которые идут после этой строки в файле. Если вы хотите быть уверены, что это применяется только к этой команде, просто поместите объявление переменной в начале команды, так же, как вы бы это сделали, меняя переменную только для одной команды в консоли:
varname=value command
Так что это может выглядеть так:
0 5 * * * varname=value command
Для личного crontab или
0 5 * * * root varname=value command
Для системного.
Примечание: Я ответил на ваш вопрос, но другие правы в том, что это, вероятно, не является причиной вашей проблемы.
В данном случае, вероятно, лучше добавить к $PATH, чем перезаписывать его.
PATH=${PATH}:/others/bin
Вы также можете отладить, что установлено в вашей переменной PATH, используя следующее:
#!/usr/bin/env bash
logger "Path-dump: "${PATH}
Вы можете проверить вывод в /var/log/syslog, и вы должны увидеть некоторый вывод:
cat /var/log/syslog | grep "Path-dump"
Это работает во всех (хорошо, в большинстве) недавних версиях Debian. Обратите внимание, что в Debian по умолчанию используется vixie версия cron
. Так что – ваши результаты могут различаться в других дистрибутивах.
Любые переменные окружения, которые вы определяете в /etc/environment
, “подхватываются” cron
. Это включает как root crontab
, так и все user crontab
.
Если вы не хотите, чтобы переменные среды широко распространялись, вы можете добавить их в отдельные crontab
(ы).
Ответ или решение
Настройка переменных окружения для CRON на Ubuntu
Проблема
У вас есть скрипт на Bash (backup.sh
), который создает архив в формате .tar.gz
и передает его на удаленный сервер, используя RSA-ключи для аутентификации. Однако при попытке запустить этот скрипт через CRON вы получаете сообщение об ошибке:
/bin/sh: /home/backup.sh: Permission denied
.
Это сообщение говорит о том, что CRON не может получить доступ к вашему скрипту, что, вероятно, связано с набором минимальных переменных окружения, передаваемых в CRON.
Шаги по решению проблемы
1. Проверка прав доступа к скрипту
Сначала вам нужно убедиться, что ваш скрипт имеет необходимые права доступа. Ваша команда ls -la backup.sh
показывает, что права доступа к файлу следующие:
-rw-r--r-- 1 root root 1053 2012-10-13 15:08 backup.sh
Эти права означают, что только пользователь root может исполнять файл, что может быть одной из причин проблемы. Вам необходимо предоставить права на исполнение для файла. Выполните следующую команду:
chmod 755 /home/backup.sh
Это даст права на чтение и исполнение для всех пользователей.
2. Проверка прав доступа к директории
Также убедитесь, что пользователь, от имени которого запускается CRON, имеет права r-x
на директорию /home
и на сам файл backup.sh
. Проверьте это с помощью команды:
ls -ld /home
ls -la /home/backup.sh
Убедитесь, что у пользователя, который запускает CRON (например, root), есть все необходимые права.
3. Установка переменных окружения
Как вы правильно заметили, CRON использует минимальный набор переменных окружения. Вы можете задать переменные окружения, которые будут доступны вашему скрипту, добавив их непосредственно в CRON. Для этого выполните следующие шаги:
- Откройте crontab для редактирования:
crontab -e
- В начале файла добавьте необходимые переменные окружения. Например:
PATH=/opt/someApp/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
- Убедитесь, что ваш скрипт выглядит следующим образом:
#!/bin/bash
PATH=${PATH}:/opt/someApp/bin
# Далее ваш скрипт
Также можно добавить отладочную информацию, чтобы проверить, какие переменные окружения установлены в CRON:
echo $PATH > /tmp/cron_path.txt
Это создаст файл /tmp/cron_path.txt
, содержащий путь, который будет использован CRON.
4. Другие рекомендации
-
Если вы хотите, чтобы переменные окружения были доступны для всех пользователей и задач CRON, вы можете задать их в файле
/etc/environment
. Это позволит избежать повторного объявления переменных в каждой задаче CRON. -
Для улучшения отладки вы можете использовать логирование в своей задачи CRON, чтобы видеть подробности о выполнении вашего скрипта. Пример записи в лог:
*/5 * * * * /home/backup.sh >> /var/log/backup.log 2>&1
Эта команда будет записывать стандартный и ошибочный вывод вашего скрипта в указанный лог-файл.
Заключение
Следуя указанным шагам, вы сможете успешно запустить ваш скрипт через CRON. Убедитесь, что вы правильно задали права доступа и переменные окружения. Если возникнут дополнительные проблемы, наличие логов выполнения скрипта может помочь лучше понять, что идет не так.