cronは、「。bashrc」および「.bash_profile」で定義された変数を無視します


49

/ etc / crontabファイルに「SHELL」変数を定義しました:

[martin@martin ~]$ grep SHELL /etc/crontab 
SHELL=/usr/local/bin/bash
[martin@martin ~]$ file /usr/local/bin/bash
/usr/local/bin/bash: ELF 32-bit LSB executable, Intel 80386, version 1 (FreeBSD), dynamically linked (uses shared libs), for FreeBSD 8.0 (800107), stripped
[martin@martin ~]$ 

さらに、/ etc / crontabファイル内のすべてのスクリプトは、ユーザー「martin」の下で開始されます。ただし、/ home / martin / .bash_profile(ログインシェル用)および/home/martin/.bashrc(非ロギングシェル用)には、cronジョブの場合は無視されますが、マシンにログインする場合に使用される変数が含まれていますSSHまたは新しいbashセッションを開きます。cronがこれらの変数を無視するのはなぜですか?cronは、ユーザー「martin」のアクセス許可で「/ usr / local / bin / bash my-script.sh」を実行するだけではありませんか?


2
Ubuntuユーザーは、Ubuntuのデフォルトに.bashrc非対話型シェルでの実行を停止する行あることに注意してください。
-joeytwiddle

回答:


72

ジョブを実行しているユーザーのスクリプトの先頭またはジョブの先頭で、必要なファイルを入手できます。「ソース」コマンドは組み込みです。これらのファイルを編集して変更をロードする場合も、同じことを行います。

* * * * * source /home/user/.bash_profile; <command>

または

#!/bin/bash
source /home/user/.bash_profile

<commands>

2
cronがbashシェルを使用していない場合、「ソース」が機能しない可能性があることに注意してください。シェルがの場合に対処できる答えを追加しましたsh
ジョナサン


23

インタラクティブなシェルではないからです。いくつかのターミナルを開いたときにも同じことが起こります。

この質問をご覧ください.bashrcファイルとは何ですか?| スーパーユーザー

また、これも:

.bashrc、.bash_profile、および.environmentの違いは何ですか?| スタックオーバーフロー

接続がログインシェル(またはそうでない)、対話型シェル(またはない)、またはその両方であるかどうかによって、異なるスクリプトが起動します。

bashrcを作成する場合は、次の変更を行う必要があります。

Bashを非対話形式で起動すると、たとえばシェルスクリプトを実行するために、環境内で変数BASH_ENVを探し、その値がそこにある場合は展開し、展開した値を読み取りおよび実行するファイルの名前として使用します。Bashは、次のコマンドが実行されたかのように動作します。

if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi 

ただし、PATH変数の値はファイル名の検索には使用されません。

上記のように、--loginオプションを使用して非対話型シェルが呼び出されると、Bashはログインシェルスタートアップファイルからコマンドを読み取って実行しようとします。

ソース:Bashスタートアップファイル| Bashリファレンスマニュアル| gnu.org


したがって、Cron内でBASH_ENVを設定すると、cronは非対話型で非ログインであるため、cron bashスクリプトがソースします。
CMCDragonkai

12

シェルが使用されているsource場合、実行できない場合がありますsh。これは、crontabに次の行を追加することで変更できます。

SHELL=/bin/bash
* * * * * source "/root/.bashrc"; <command>

環境を指定することもできます。

BASH_ENV="/root/.bashrc"
* * * * * <command>

または、ローカル/home/user/.bashrcのユーザーcronジョブ(たとえばcrontab -e)を使用できます。

が存在する場合、.bash_profile置き換えられることに注意してください.bashrc

クレジット:cronシェルを変更する方法(shからbash)


これはAcquia Cloudのスケジュールされたジョブ(基本的にはcronジョブ)でもうまく機能します。:あなたは次のように、同じことを行うことができますSHELL=/bin/bash && source /home/YOUR_USER_NAME/.bash_profile && sh ....
アレハンドロ・モレノ

1

.bashrccronjobからのソースを妨げる可能性のある他の何かは、このファイルが対話型シェルを検出するために行うチェックです。

たとえば、Ubuntu 18.04では、.bashrcユーザーのデフォルトは次のように始まります。

# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

ソーシングを実行しても、すぐに終了するため、何の役にも立ちません。


1

次の-lようなオプションでbashを呼び出すことができます。

* * * * * /bin/bash -l /path/to/script arg1 arg2

この-lオプションは、bashをログインシェルにします。したがって、ユーザーのを読み取ります.bash_profile.bashrcによって明示的にソースされない限り、ユーザーの読み取りはしません.bash_profile。これは、非対話型シェルが自動的に読み取らないため.bashrcです。しかし、対話型シェルに役立つ設定を行う.bashrcために、cronジョブは必要ありません。.bashrc

バリエーション:

bashがPATH上にある場合、絶対パスを指定する必要はありません。

* * * * * bash -l /path/to/script arg1 arg2

最適化は、次を使用して現在のシェルを置き換えることexecです。

* * * * * exec bash -l /path/to/script arg1 arg2

1

bashシェルであるか通常のプログラミング言語perlまたはpython)であるかによって動作が異なります。

設計により、内の設定~/.bash_profile~/.bashrcときなどは、セット物事へのユーザーのためのものであるbash果たしているシェルの役割(ログインシェル、interractiveシェル)。xterm(対話型シェル)またはsshセッション(ログインシェル)またはコンソール(ログインシェル)にある環境について考えてください。

一方、bashまた、強力なプログラミング言語(サービスを管理するための多くのスクリプトを考えsystemdてください)は、異なるスタイルの作業を必要とします。たとえば、開発者がシステムスクリプトまたはbashプログラムを作成している場合、開発者はユーザーのソースを~/.bash_profile自動的に取得したくないでしょう。これは通常のプログラムであり、シェルではありません。(を含む通常のプログラムbashのプログラムは)当然だろう継承現在の作業evironement(シェル)の設定が、ではなく、設定し、それらを。

cronin bash–のプログラムを記述すると、たまたま書き込まれbashます。実際には、我々はそれを書くことができるpythonか、perlまたはその他のprogammingはその後、我々はソースにオプション持つことができ、言語bashのを~/.bash_profile(読み:ちょうどあなたのプログラミング言語と同じ言語であることを起こるユーザのシェルの設定します):

[ -f /home/user/.bash_profile ] && . /home/user/.bash_profile

ただし、その特定のユーザーがbash自分のシェルとして使用しない場合はどうなりますか?彼/彼女が使用することができzshkshfish、などだから、公共の使用のためのプログラムを書くとき、その練習は実際に動作しないでしょう。

だから、それが~/.bash_profileうまくいくと思うなら、あなたは調達することができます。しかし、ここでは、ファイルを調達できるかどうかではなく、システム内で物事がどのように機能するかということです。設計コンセプトです。要するに:我々は、表示すべきであるbashシェルとprogamming言語:2つの役割を持つものとして。そうすれば、すべてが理解しやすくなります。


0

NVMを使用するcronからノードアプリケーションを実行するときに同じ問題が発生しました。bashシェルがcronから.bashrcファイルを読み取るようにするには、bashコマンドをインタラクティブシェルオプション `-lで呼び出します。

例えば: * * * * * /bin/bash -lc '/home/user/myapp.sh restart'

うまくいかない場合は、crontabでパス変数を設定してみてください

41 7 * * * /bin/bash -lc "PATH=$PATH:/home/user/.nvm/versions/node/v8.10.0/bin && /home/user/script.sh restart "

-1

それに対処する私の方法はこれでした:

1)(最後の)に変数を入れる~/.profile

myVarInDotProfile="someValue"

2)私の(毎日)cronタスク(のためのbashスクリプトを作成する~/cronDaily.sh私の命令に加えての繰り返しの調達を含みます)~/.profle

source ~/.profile
command ${myVarInDotProfile}/

3)スクリプトの実行をからスケジュールして、crontab毎日実行します:

0 0 * * * bash ~/cronDaily.sh

私の変数は無視されず、コマンドは正常に実行されました。


このような強力な調達~/.profileは問題があると言う人もいます。私の特定のケースでは、なぜそれが問題なのかわかりませんが、専用のファイルを作成することを検討することをお勧めします。

一般的に、これにはもっと良い方法があるかもしれませんが、それは多くの苦痛の後に私のために働いたものであり、それはBash 4.3.46の時点で、からファイルをソースできないという原則を説明しcrontabます

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.