Cronjob не выполняет script, который отлично работает автономно
У меня есть файл php script в /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 работает не так, как ожидалось.
Что может быть неправильным?
Ответы
Ответ 1
Как видно из комментариев, проблема заключается в том, что вы не определяете, какую программу следует использовать для выполнения script. Учтите, что cronjob выполняется в крошечной среде; там не так много можно предположить. Вот почему мы определяем полные пути и т.д.
Итак, вам нужно сказать что-то вроде:
1 * * * * /bin/sh /var/www/html/dbsync/dbsync.sh /var/www/html/dbsync
# ^^^^^^^
/bin/sh
является двоичным файлом, который вы хотите использовать для выполнения script.
В противном случае вы можете установить разрешения на выполнение для script и добавить заголовок shell- script, чтобы сообщить, какой интерпретатор использовать:
#!/bin/sh
Если вы это сделаете, добавление пути двоичного файла не требуется.
От Устранение общих проблем с заданиями cron:
Использование относительных путей. Если ваше задание cron выполняет script некоторых вы должны обязательно использовать только абсолютные пути внутри script. Например, если ваш script находится по адресу /path/to/ script.phpand вы пытаетесь открыть файл с именем file.php в том же каталоге, вы не можете использовать относительный путь, например fopen (file.php). Файл должен вызывается из его абсолютного пути, например: fopen (/path/to/file.php). Это связано с тем, что задания cron не обязательно запускаются из каталога в который находится script, поэтому все пути должны быть вызваны специально.
Кроме того, я понимаю, что вы хотите запускать это каждую минуту. Если это так, 1 * * * *
не будет. Intead, он будет запускать каждую первую минуту минута каждый час. Поэтому, если вы хотите запускать его каждую минуту, скажите * * * * *
.
Ответ 2
Важно понимать "login shell" и "интерактивная оболочка", что они означают.
- login shell: коротко, когда вы входите в ssh-сессию и получаете окно терминала, в котором вы можете вводить команды оболочки. После входа в систему система выполняет некоторые файлы (.bashrc) и устанавливает для вас переменные среды, такие как переменная PATH.
- интерактивная оболочка: после входа в систему вы можете запускать вручную терминалы оболочки. Система выполняет некоторый файл профиля, назначенный вашей учетной записи (.bash_profile,.bash_login,.profile). Эти файлы также устанавливают некоторые переменные среды и инициализируют переменную PATH для вашего открытого сеанса оболочки.
В ОС начались сценарии оболочки, а задания cron не соответствуют указанному выше способу для запуска оболочки. Поэтому никаких системных сценариев (.bashrc) или профилей пользователей не выполняется. Это означает, что наша переменная PATH не инициализируется. Команды Shell не могли найти, потому что переменная PATH не указывает на нужные места.
Это объясняет, почему ваш script работает успешно, если вы запускаете его вручную, но не удается, когда вы запускаете его через crontab.
Решение-1:
Используйте абсолютный путь для каждой команды оболочки вместо имени команды, используемой в файле script.
- вместо "awk" использовать "/usr/bin/awk"
- вместо "sed" использовать "/bin/sed"
Решение-2: Инициализировать переменные среды и особенно переменную PATH перед выполнением сценариев оболочки!