既存の環境変数を使用してcronコマンドを実行するにはどうすればよいですか?
シェルプロンプトにいる場合は、echo $Oracle_HOME
と入力してパスを取得できます。これは、~/.profile
で設定される環境変数の1つです。ただし、~/.profile
がcronスクリプトから読み込まれないため、$Oracle_HOME
変数が設定されていないため、スクリプトが失敗します。
この質問 で、著者はcronの変数を設定する~/.cronfile
プロファイルを作成することについて言及し、次に彼はすべてのcronコマンドを~/Cron
ディレクトリに保持するスクリプトにロードするための回避策を実行します。 ~/.cronfile
のようなファイルは良い考えのように聞こえますが、残りの答えは少し扱いにくいようで、誰かが同じ結果を得る簡単な方法を教えてくれることを望んでいました。
スクリプトの最初にsource ~/.profile
のようなものを追加できると思いますが、それは冗長であるように思えます。
では、cronスクリプトでインタラクティブシェルプロファイルから変数をロードするにはどうすればよいですか?
Crontabで、コマンドの前に. $HOME/.profile
を追加します。例えば:
0 5 * * * . $HOME/.profile; /path/to/command/to/run
Cron
はシェルについて何も知りません。システムによって開始されるため、最小限の環境です。何かが必要な場合は、それを自分で持ってくる必要があります。
私がより簡単だと思う別のオプションは、cronでスクリプトを実行し、スクリプト内に環境を含めることです。
Crontab -eファイルで:
Shell=/bin/bash
*/1 * * * * $HOME/cron_job.sh
Cron_job.shファイル:
#!/bin/bash
source $HOME/.bash_profile
some_other_cmd
.bash_profileのソースの後のコマンドは、ログインした場合と同じように環境を設定します。
私がより簡単だと思う別のオプションは、cronでスクリプトを実行し、bashにログインするように指示することです(したがって、/etc/profile.d/...
環境定義を使用)
crontab -e
ファイル:
*/1 * * * * bash -l -c './cron_job.sh'
*/1 * * * * bash -l -c 'php -f ./cron_job.php'
.bash_profile
のソースの後のコマンドは、ログインした場合と同じように環境を設定します。
悪いアイデア。一般的な方法は、cronジョブから実行されるスクリプトに必要なすべての環境変数を具体的に設定することです。
この構文は間違いなく役立ちます。構文はわかりませんが、動作します。 Oracleは、Oracle Configuration Managerをcrontabにデプロイするときにこの構文を使用するため、これが正しいソリューションであると私は信じています。
0 5 * * * SOME_ENV_VAR=some_value some_command some_parameters
グローバル環境変数を/etc/environment
。これらは、プログラムがcrontabによって実行されるときにロードされます。例:
env | grep Oracle_HOME >> /etc/environment
service crontab restart
欠点は、それが単一のユーザーに制限されないことです。 CentOS7でテスト済み
最近、cronジョブ全体をrootとして実行する必要があり、同時にサブコマンドを別のユーザーとして実行しなければならないというケースに遭遇しました(そのユーザーの環境を調達する必要がありました)。私は次のアプローチで行きました:
# m h dom mon dow user command
*/5 * * * * root (Sudo -i -u <the user> command-to-be-run-as-user) && command-to-be-run-as-root
重要な部分は引数-i
Sudo
に渡されます。これにより、別のログインシェルで指定されたコマンドが実行されます(つまり、ユーザーのドットファイルが読み込まれます)。
PS:user
列は/etc/crontab
そしてその /etc/cron.d/*
ファイル。
はい、「よく知られた回避策」を使用できます(そのうちいくつかはリストされています)。これは、誰もがそれがくだらないことであることを知っていると言う別の言い方ですが、一部の人々は、これを「セキュリティ機能」と呼ぶでしょう。無駄な時間は無駄ではありませんでした。これは、QWERTYキーボードに相当するcronです。
元々の理由はパフォーマンスのためだったのではないかと思います。1分間に1回実行されるスクリプトは、rcスクリプトを読み取るための時間を費やさないからです。また、元々cronは実際には構成可能ではなかったため、デフォルトが本当に唯一のオプションでした。
ユーザーが愚かなシェル体操を行わなくても、cronがインタラクティブシェルの環境を引き継ぐだけの簡単な構成や方法がないことによるセキュリティの追加はありません。最近のマシンでは、毎分大量のジョブを実行しない限り、一般に知覚できるパフォーマンスの向上はありません。
Unix文化は失敗します。私の愚見で。 :-)
プロファイルを設定する代わりに、PATH
を設定することが私に役立ちました。 PATH
が異なるため、一部のコマンドはcronスクリプトで使用できませんでした。
ENVIRONMENT=prod
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
*/30 * * * * /opt/myscript1.sh
*/30 * * * * /opt/myscript2.sh
*/30 * * * * /opt/myscript3.sh
コマンドのパスでPATH
を設定すると役に立ちました。テンプレートを使用して後でテンプレートを解除できる場合はさらに便利です。
ENVIRONMENT={{ENVIRONMENT}}
PATH={{PATH}}
*/30 * * * * /opt/myscript1.sh
*/30 * * * * /opt/myscript2.sh
*/30 * * * * /opt/myscript3.sh
各項目に変数を渡すのは面倒に見えます。
私にとってうまくいった解決策は here で説明されています。
. ~/.cronfile
を呼び出すラッパースクリプトを作成し、必要な処理を行います。このスクリプトはcronによって起動されます。
~/.cronfile
では、cronジョブの環境を指定します。