コマンドラインから実行すると機能するスクリプトがありますが、cron
を使用してスケジュールすると、ファイルやコマンドが見つからないというエラーが発生します。私の質問は2つあります。
crontab -e
を使用してcronジョブをスケジュールすると、権限のベースとして自分のユーザーIDが使用されますか?または、ある種のcronユーザーIDとそれに関連する権限を使用していますか?
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 [email protected] < 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
も実行できませんが、ユーザーとしては実行できます。これを適切に機能させるには何が欠けていますか?
追加 cd /home/xxxx/Documents/Scripts/
ジョブをそのディレクトリで実行する場合。 cronがその特定のディレクトリに移動する理由はありません。 Cronはホームディレクトリでコマンドを実行します。
ssmtp
については、デフォルトのPATH
にない可能性があります。 Cronのデフォルトパスは実装に依存しているので、manページを確認してください。ただし、ssmtp
は/usr/sbin
これはデフォルトのPATH
ではなく、ルートのみです。
PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin
15 7 * * * cd /home/xxxx/Documents/Scripts && ./email_ip_script.sh
Cronjobがbashスクリプトの場合、以下はCDでスクリプトの場所に移動します(cron定義で絶対パスを使用していると想定しています)。
cd "$(dirname "$0")";
質問1に答えるには、crontab -e
自分のユーザーとして、ジョブはそのユーザーのcrontabでスケジュールされ、そのユーザーの権限で実行されます。
ただし、ジョブが非対話型シェルで実行されること、つまり、$ PATHがコマンドラインからスクリプトを実行するときの$ PATHと異なる場合があることを考慮する必要があります。
特にat/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 [email protected] < $mailmsg
/bin/rm $mailmsg
cron
は、各ユーザーのスケジュールされたジョブをそのユーザーとして実行します。これで、ホームディレクトリを基準にしてスクリプトを実行することができます。
別の場所から実行する必要がある場合は、スクリプトでcd
を使用してその場所に移動します。
ssmtp
は、おそらくcron
のデフォルトのPATHにはありません(ほとんどのプラットフォームでは、設計により非常に狭く設定されています)。スクリプトでssmtp
への完全パスを指定するか、a)すべてのスクリプトで使用できるcrontabファイル、またはb)各スクリプトでPATHを明示的に設定できます。
チェック this スレッドを使用して、cronの環境を簡単に見つける方法を確認します。これは、インタラクティブシェルで使用するよりもはるかに少ない方法です。何も設定されていないと想定し、自分で明示的に設定するのが最善です。
ジョブの実行におけるcron
のデフォルトの作業ディレクトリはホームディレクトリであり、通常は/home/your-user-name
。
@Kusalanandaの優れたコメントを採用。
一部の人々はそれをほのめかしたりリンクしたりしましたが、私のディストリビューションのmanドキュメントでそれを見つけることができないので見つけるための最良の方法は、これをcronに追加することです
* * * * * echo $PATH > /tmp/lolcronjobs
私の場合、ubuntuはデフォルトで/usr/bin:/bin
いくつかの問題が発生しました。