似たような質問がたくさんあることは知っていますし、いろいろ試してみましたが、まだうまくいきません。
10分で実行するようにスケジュールされているcronjobがあります。 /var/log/syslog
で、正常に実行されていることがわかります
Oct 21 07:30:01 stan CRON[7604]: (stan) CMD (stan /home/stan/update.sh)
Oct 21 07:40:01 stan CRON[8304]: (stan) CMD (stan /home/stan/update.sh)
Oct 21 07:50:01 stan CRON[8751]: (stan) CMD (stan /home/stan/update.sh)
Oct 21 08:00:01 stan CRON[9347]: (stan) CMD (stan /home/stan/update.sh)
Oct 21 08:10:01 stan CRON[9789]: (stan) CMD (stan /home/stan/update.sh)
update.sh
call php
データベースを更新するスクリプト。ターミナルから直接実行すると、シェルスクリプトデータベースが更新され、完全に機能します。
./update.sh
しかし、cronjobからはデータベースが更新されません。私のcron
*/10 * * * * stan /home/stan/update.sh
シェルスクリプトから生成されるコマンドは
/usr/bin/php /var/www/html/site/update.php
両方のファイルの許可
-rwxrwxr-x 1 stan stan 123 Oct 20 15:09 update.sh
-rwxr-xr-x 1 stan www-data 1301 Oct 21 07:52 /var/www/html/site/update.php
何が問題になるのでしょうか?
更新:PATH
$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
update.sh
$ cat update.sh
#!/bin/sh
list="/var/www/html/site"
config="/usr/bin/php"
for i in "$list"
do
"$config" "$i"/update.php
done
参照 シェルとphpについてだった昨日からの私の質問はcronについてです。
$ whereis php
php: /usr/bin/php5.6 /usr/bin/php /usr/lib/php /etc/php /usr/include/php /usr/share/php5.6-intl /usr/share/php7.0-mbstring /usr/share/php7.0-common /usr/share/php5.6-curl /usr/share/php5.6-Gd /usr/share/php5.6-mcrypt /usr/share/php5.6-common /usr/share/php5.6-readline /usr/share/php5.6-json /usr/share/php /usr/share/php5.5-mbstring /usr/share/php5.6-opcache /usr/share/php5.6-mbstring /usr/share/php5.6-xml /usr/share/php5.5-common /usr/share/php5.6-mysql /usr/share/man/man1/php.1.gz
$ which php
/usr/bin/php
cron
ジョブを呼び出す2つの異なる方法を混同しているようです。
Ubuntuは、スプール領域/var/spool/cron
に格納されているユーザーcrontabs
と、/etc/crontab
および/etc/cron.d
のファイルから実行されるシステム全体のcronジョブの両方をサポートするやや混乱したポリシーをDebianから継承します。
/etc/crontab
で指定されたジョブまたは/etc/cron.d
のファイルを介して指定されたジョブは、別のユーザーとして実行できるように追加のフィールドが必要なので、形式は次のようになります。
*/10 * * * * <username> <command> <args>
crontab -e
(またはルートの場合はSudo crontab -e
)を使用してスプール領域を介してセットアップされたジョブは、すでに特定のユーザーに属しているため、ユーザーフィールドは不要です。
*/10 * * * * <command> <args>
crontab -e
コマンドを介して設定されたcronジョブにユーザー名フィールドを含めると、コマンドとして誤って解釈されます。ログ出力からわかるように、
Oct 21 07:30:01 stan CRON[7604]: (stan) CMD (stan /home/stan/update.sh)
cron
はstan
をcommand with argument/home/stan/update.sh
として解釈しています
解決策は、単にcrontabからユーザー名stan
を削除することです。
考えられるいくつかの問題:
1)#!/bin/sh
の最初の行にupdate.sh
がない場合があります
2)PHPは追加のコマンドを実行する必要がある場合がありますが、cronジョブはPATH変数を設定せずに実行されます。これを修正するには、コマンドが機能する端末でecho $PATH
を使用してからexport PATH=...
を使用し、...
を上記のecho $PATH
の出力に置き換えます
3)PHPは、機能するために他の環境変数を必要とする場合があります。それらを追跡し、update.sh
を呼び出す前に/usr/bin/php
にエクスポートします。
編集
OK、そうではありません1)
新しいウィンドウ(または新しいssh接続)を開き、次を実行します。
for i in `env | sed 's/=.*//'` ; do unset $i ; done
これにより、PATHを含むすべての環境変数が設定解除されます。次に試してください:
/usr/bin/php /var/www/html/site/update.php
次に、エラーメッセージをここに投稿します。
問題は、crontabの非常に限られたパス変数検索です。すべてのスクリプトおよび下付き文字のほとんどすべてのコマンドに追加するには、フルパスを追加する必要があります。または、スクリプトを手動で実行するときと同じ検索パスをスクリプトに追加できます。
変更元:
#!/bin/sh
list="/var/www/html/site"
config="/usr/bin/php"
for i in "$list"
do
"$config" "$i"/update.php
done
変更先:
#!/bin/sh
PATH=$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
list="/var/www/html/site"
config="/usr/bin/php"
for i in "$list"
do
"$config" "$i"/update.php
done
注:
追加されたパス検索は、質問で投稿したものから取得されたもので、スクリプトを手動で実行すると機能します。 update.php
スクリプトによって呼び出されるスクリプトまたはコマンドとともに、スクリプトからのコマンドが含まれるパスがわかっている場合、追加する必要があるのはそれらの検索パスのみです