Cronjob не выполняет сценарий, который работает нормально автономно
У меня есть файл php скрипта в /var/www/html/dbsync/index.php
, когда cd /var/www/html/dbsync/
и беги php index.php
это работает отлично.
Я хочу вызвать PHP-файл через sh-файл, расположение SH-файла указано ниже
/var/www/html/dbsync/dbsync.sh
Это содержание dbsync.sh
файл:
/usr/bin/php /var/www/html/dbsync/index.php >> /var/www/html/dbsync/myscript.log 2>&1 -q -f
Когда я cd /var/www/html/dbsync/
и беги ./dbsync.sh
это работает отлично, а также.
Теперь, если я настрою crontab, как показано ниже:
1 * * * * /var/www/html/dbsync/dbsync.sh /var/www/html/dbsync
Тем не менее, этот crontab не работает, как ожидалось.
Что может быть не так?
3 ответа
Как видно из комментариев, проблема в том, что вы не определяете, какую программу следует использовать для выполнения скрипта. Примите во внимание, что cronjob выполняется в крошечной среде; там мало что можно предположить. Вот почему мы определяем полные пути и т. Д.
Так что вам нужно сказать что-то вроде:
1 * * * * /bin/sh /var/www/html/dbsync/dbsync.sh /var/www/html/dbsync
# ^^^^^^^
/bin/sh
будучи двоичным файлом, который вы хотите использовать для выполнения скрипта.
В противном случае вы можете установить разрешения на выполнение скрипта и добавить заголовок shell-скрипта, сообщающий ему, какой интерпретатор использовать:
#!/bin/sh
Если вы сделаете это, добавление пути двоичного файла не требуется.
Из раздела Устранение распространенных проблем с заданиями cron:
Используя относительные пути. Если ваша задача cron выполняет какой-либо сценарий, вы должны обязательно использовать только абсолютные пути внутри этого сценария. Например, если ваш скрипт находится по адресу /path/to/script.php и вы пытаетесь открыть файл с именем file.php в том же каталоге, вы не можете использовать относительный путь, например fopen(file.php). Файл должен вызываться по абсолютному пути, например: fopen(/path/to/file.php). Это связано с тем, что задания cron не обязательно выполняются из каталога, в котором находится скрипт, поэтому все пути должны вызываться специально.
Кроме того, я понимаю, что вы хотите запускать это каждую минуту. Если так, 1 * * * *
не буду делать Интеад, он будет запускаться каждую минуту после каждого часа. Так что, если вы хотите запустить его каждую минуту, скажем, * * * * *
,
Важно понимать, что означают "оболочка входа" и "интерактивная оболочка".
- login shell: кратко, когда вы входите в сессию ssh и получаете окно терминала, где вы можете вводить команды оболочки. После входа в систему система запускает некоторые файлы (.bashrc) и устанавливает некоторые переменные окружения, такие как переменная PATH.
- интерактивная оболочка: после входа в систему вы можете запустить вручную оболочку терминала (ов). Система выполняет какой-то файл профиля, назначенный вашей учетной записи (.bash_profile, .bash_login, .profile). Эти файлы также устанавливают некоторые переменные окружения и инициализируют переменную PATH для вашего открытого сеанса оболочки.
Под управлением ОС запускаются сценарии оболочки, а задания cron не подходят вышеупомянутым способом запуска оболочки. Поэтому никакие системные скрипты (.bashrc) или профили пользователей не выполняются. Это означает, что наша переменная PATH не инициализирована. Команды оболочки не найдены, поскольку переменная PATH не указывает на правильные места.
Это объясняет, почему ваш скрипт работает успешно, если вы запускаете его вручную, но не запускается при запуске через crontab.
Решение-1: Используйте абсолютный путь каждой команды оболочки вместо только имени команды, используемого в ваших файлах скриптов.
- вместо "awk" используйте "/usr/bin/awk"
- вместо "sed" используйте "/bin/sed"
Решение-2: Инициализируйте переменные среды и особенно переменную PATH перед выполнением сценариев оболочки!
способ 1, добавьте этот заголовок в свой dbsync.sh:
#!/bin/bash -l
метод 2, добавьте bash -l в ваш файл cron:
1 * * * * bash -l /var/www/html/dbsync/dbsync.sh /var/www/html/dbsync