通常cronには環境が設定されていないため、cronのスクリプトの実行方法にいくつかの問題があります。 cronと同じようにbash(?)を呼び出す方法はありますか。スクリプトをインストールする前にテストできますか?
これをcronに追加します:
30 08 * * * env > ~/cronenv
実行後、次を実行します。
env - `cat ~/cronenv` /bin/sh
これは、cronが/ bin/shを実行することを前提としています。これは、ユーザーのデフォルトシェルに関係なくデフォルトです。
Cronはデフォルトでこの環境のみを提供します:
HOME
ユーザーのホームディレクトリLOGNAME
ユーザーのログインPATH=/usr/bin:/usr/sbin
Shell=/usr/bin/sh
さらに必要な場合は、crontabのスケジューリングテーブルの前に環境を定義するスクリプトを入手できます。
いくつかのアプローチ:
cron envをエクスポートしてソース:
追加
* * * * * env > ~/cronenv
あなたのcrontabに、それを一度実行させて、それをオフに戻してから実行してください
env - `cat ~/cronenv` /bin/sh
そして今、あなたはcronの環境を持つsh
セッションの中にいます
環境をcronに移行する
上記の演習をスキップして、cronジョブの前で. ~/.profile
を実行できます。
* * * * * . ~/.profile; your_command
画面を使用
上記の2つのソリューションは、dbus
などにアクセスできる実行中のXセッションに接続された環境を提供するという点で依然として失敗します。たとえば、Ubuntuでは、nmcli
(Network Manager)ただし、cronでは失敗します。
* * * * * /usr/bin/screen -dm
上記の行をcronに追加し、一度実行してから、オフにします。スクリーンセッションに接続します(screen -r)。スクリーンセッションが(ps
で)作成されたことを確認する場合、それらが大文字である場合があることに注意してください(例:ps | grep SCREEN
)
これで、nmcli
および同様のものも失敗します。
以下を実行できます。
env - your_command arguments
これにより、空の環境でyour_commandが実行されます。
アカウントのシェルに応じて
Sudo su
env -i /bin/sh
または
Sudo su
env -i /bin/bash --noprofile --norc
から http://matthew.mceachen.us/blog/howto-simulate-the-cron-environment-1018.html
6年後の回答:環境の不一致の問題は、cronの代替としてsystemd
"timers"によって解決される問題の1つです。 systemdの「サービス」をCLIから実行する場合でも、cron経由で実行する場合でも、まったく同じ環境を受け取り、環境の不一致の問題を回避します。
Cronジョブが手動で渡されたときに失敗する最も一般的な問題は、cronによって設定された制限付きのデフォルト$PATH
です。これはUbuntu 16.04では次のとおりです。
"/usr/bin:/bin"
対照的に、Ubuntu 16.04でsystemd
によって設定されるデフォルトの$PATH
は次のとおりです。
"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
そのため、systemdタイマーがさらに手間をかけずにバイナリを見つける可能性がすでにあります。
Systemdタイマーの欠点は、それらをセットアップする時間がもう少し長いことです。最初に「サービス」ファイルを作成して実行するものを定義し、「タイマー」ファイルを実行してスケジュールを定義し、最後にタイマーを「有効化」してアクティブにします。
Envを実行し、stdoutをファイルにリダイレクトするcronジョブを作成します。 「env-」と一緒にファイルを使用して、cronジョブと同じ環境を作成します。
Cronの親はinitなので、制御端末なしでプログラムを実行することを忘れないでください。次のようなツールでそれをシミュレートできます。
デフォルトでは、cron
は、システムのsh
の考えが何であれ、そのジョブを実行します。これは、実際のBourne Shellまたはdash
、ash
、ksh
、またはbash
(または別の1つ)がsh
にシンボリックリンクされている可能性がありますPOSIXモード)。
最善の方法は、スクリプトに必要なものがあることを確認し、何も提供されていないことを前提とすることです。したがって、完全なディレクトリ仕様を使用し、$PATH
などの環境変数を自分で設定する必要があります。
私が見つけたもう1つの簡単な方法(ただし、エラーが発生する可能性があるため、まだテスト中です)は、コマンドの前にユーザーのプロファイルファイルを取得することです。
/etc/cron.d/スクリプトの編集:
* * * * * user1 comand-that-needs-env-vars
になります:
* * * * * user1 source ~/.bash_profile; source ~/.bashrc; comand-that-needs-env-vars
汚れていますが、仕事は完了しました。ログインをシミュレートする方法はありますか?実行できるコマンドだけですか? bash --login
は機能しませんでした。しかし、それがより良い方法だと思われます。
編集:これは堅実な解決策のようです: http://www.epicserve.com/blog/2012/feb/7/my-notes-cron-directory-etccrond-ubuntu-1110/
* * * * * root su --session-command="comand-that-needs-env-vars" user1 -l
回答 https://stackoverflow.com/a/2546509/55934 は、cron環境を取得してスクリプトに使用する方法を示しています。ただし、使用するcrontabファイルによって環境が異なる可能性があることに注意してください。 env > log
経由で環境を保存するために、3つの異なるcronエントリを作成しました。これらは、Amazon Linux 4.4.35-33.55.amzn1.x86_64での結果です。
MAILTO=root
Shell=/bin/bash
USER=root
PATH=/sbin:/bin:/usr/sbin:/usr/bin
PWD=/
LANG=en_US.UTF-8
SHLVL=1
HOME=/
LOGNAME=root
_=/bin/env
crontab -e
)Shell=/bin/sh
USER=root
PATH=/usr/bin:/bin
PWD=/root
LANG=en_US.UTF-8
SHLVL=1
HOME=/root
LOGNAME=root
_=/usr/bin/env
MAILTO=root
Shell=/bin/bash
USER=root
PATH=/sbin:/bin:/usr/sbin:/usr/bin
_=/bin/env
PWD=/
LANG=en_US.UTF-8
SHLVL=3
HOME=/
LOGNAME=root
最も重要なのは、PATH
、PWD
、およびHOME
が異なることです。安定した環境に依存するように、これらをcronスクリプトで設定してください。