55

cron と crontab を使用してタスクをスケジュールするのは初めてです。ログオンしてターミナルを開いて自分で実行したかのように、タスクの実行をスケジュールしようとしています。

ただし、スケジュールされたタスクが実行されている $USER と $PATH を監視するのに役立つタスクをスケジュールしました。これが私が見つけたものです。

$ crontab -l
41 11 * * * echo "USER: $USER" > ~/Desktop/cron_env.log; echo "PATH: $PATH" >> ~/Desktop/cron_env.log
$ cat ~/Desktop/cron_env.log
USER:
PATH: /usr/bin:/bin

$USER が設定されていないように見え、$PATH は非常に基本的なものやデフォルトのものです。逆に、ターミナルを開いて (ログインして)、同じ情報をエコーすると、次のように表示されます。

USER: aschirma
PATH: /usr/lib/jvm/java-6-sun/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/pkg/icetools/bin:/pkg/hwtools/bin:/pkg/netscape/bin:/pkg/gnu/bin

crontab タスクを希望どおりに実行するには、どうすればよいですか?

4

5 に答える 5

85

「man 5 crontab」によると、cron行の前に書き込むことで、crontabに環境変数を設定できます。

crontab の例もあるので、コピーして貼り付けるだけです。

$ man 5 crontab | grep -C5 PATH | tail 
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# m h dom mon dow usercommand
17 * * * *  root  cd / && run-parts --report /etc/cron.hourly
25 6 * * *  root  test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6 * * 7  root  test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )

したがって、PATH または任意の環境変数を必要に応じて調整できます。しかし、この例は典型的なケースには十分に思えます。

于 2013-02-04T19:59:16.513 に答える
16

*ix では、プロセスは通常、fork+exec を介して親プロセスから環境を継承します。環境をクリアするオプションがありますが、通常はそうではありません。プロセス ツリーは ps axf で、環境変数は ps axfe で見ることができます。

cron は通常、誰かのシェルの子ではないため、対話型シェルとは異なる環境を持つことがよくあります。ただし、一貫性を保つために、cronが意図的に独自の環境をクリアする可能性は十分にあります。

私は自分の cron ジョブ (議論のために「foo」) をインタラクティブなシェルで次のようにテストするのが好きです: env - ./foo これは実際には cron が行うより多くの環境変数をクリアしますが、より簡単に取得できるようにします。あなたがテストしているものはより似ているので、IMOに行きます。依存している変数 ($PATH など) を設定するか、別のものに置き換える必要があります。たとえば、$USER は $(whoami) になります。

また、「set -eu」と「set -o pipefail」を使用する bash スクリプトを作成することも好きです。-eu は「ゼロ以外の終了コードで終了し、未定義の変数参照で終了する」と言い、pipefail は「パイプラインで最後の終了コードを返さず、代わりにパイプラインでゼロ以外の最初の終了コードを返す」と言う. あなたの場合、 set -u が特に役立つかもしれません。

于 2012-04-12T18:37:17.447 に答える
3

crontab はデーモンまたはサービスであるため、ログインしているユーザーなどとは異なります。環境変数が必要な場合は、自分で設定する必要があります。ただし、これらの変数のほとんどは、シェルによって /etc/profile パスから設定され、カスタム変数が $HOME ディレクトリに移動されます。

次のように /etc/profile を「ソーシング」することで、それらのいくつかを設定できる場合があります。

41 11 * * * /home/<me>/cron_env.sh
どこcron_env.shに次のようなものが含まれます:
#!/bin/sh
source /etc/profile
/usr/bin/env > /home/<me>/cron_env.log

于 2012-04-12T18:29:49.650 に答える
3

私たちの環境では、ルートが許可されている唯一の cron であり、各コマンドは通常、次のように su -c コマンドを介してアプリケーション固有のユーザーとして実行されるため、通常、この問題はありません。

su - myuser -c "/usr/local/scripts/app.sh" 2>&1

「-」オプションが指定されているため、myuser のプロファイルと環境を取得します。最近、正常に完了するために root の権限が必要なコマンドで問題が発生したため、su -c なしでコマンドを発行しました。ある程度の調査の結果、root の環境を取得する最も簡単な方法は、他のすべてのアプリケーションと同じ手法を root に使用することであることが判明したため、以下を発行しました。

su - root -c "/usr/local/scripts/app.sh" 2>&1
于 2015-07-29T20:00:55.033 に答える
1

crontab は bash スクリプトではないため、通常はシェルで使用できる環境変数を使用できません。

そのすべてのコードをシバン化されたスクリプト ファイル (「#!/bin/bash」の行で始まるファイル) に移動して、そのスクリプトを crontab で実行してみてください。

よくわかりませんが、crontabファイル内でアクセスできるのはPATH(および設定した場合はEMAILかもしれません)だけかもしれません。

編集: crontab 5 の man ページを確認してください。かなりの数の環境変数が利用可能で、すべて cron デーモンによって設定されています。

于 2012-04-12T18:25:15.457 に答える