Cronはcrontabユーザーのパスを使用しませんが、独自のパスを持っています。PATH=/foo/bar
crontabの先頭に追加すると簡単に変更できます。一般的な回避策は、常にcronが実行するコマンドの絶対パスを使用することです。しかし、cronのデフォルトPATHはどこで定義されていますか?
Archシステム(cronie 1.5.1-1)で次のコンテンツでcrontabを作成し、Ubuntu 16.04.3 LTSシステムでテストしてみたところ、同じ結果が出ました。
$ crontab -l
* * * * * echo "$PATH" > /home/terdon/fff
出力される内容は次のとおりです。
$ cat fff
/usr/bin:/bin
しかし、なぜ?デフォルトシステムのフルパスが設定されていますが、/etc/profile
他のディレクトリも含まれています。
$ grep PATH= /etc/profile
PATH="/usr/local/sbin:/usr/local/bin:/usr/bin"
/etc/environment
関連する他のコンテンツがないか、/etc/profile.d
cronが別のファイルを読み取ることができると思います。
$ grep PATH= /etc/profile.d/* /etc/environment
/etc/profile.d/jre.sh:export PATH=${PATH}:/usr/lib/jvm/default/bin
/etc/profile.d/mozilla-common.sh:export MOZ_PLUGIN_PATH="/usr/lib/mozilla/plugins"
/etc/profile.d/perlbin.sh:[ -d /usr/bin/site_perl ] && PATH=$PATH:/usr/bin/site_perl
/etc/profile.d/perlbin.sh:[ -d /usr/lib/perl5/site_perl/bin ] && PATH=$PATH:/usr/lib/perl5/site_perl/bin
/etc/profile.d/perlbin.sh:[ -d /usr/bin/vendor_perl ] && PATH=$PATH:/usr/bin/vendor_perl
/etc/profile.d/perlbin.sh:[ -d /usr/lib/perl5/vendor_perl/bin ] && PATH=$PATH:/usr/lib/perl5/vendor_perl/bin
/etc/profile.d/perlbin.sh:[ -d /usr/bin/core_perl ] && PATH=$PATH:/usr/bin/core_perl
当然、どのファイルにも関連性がなく、/etc/skel
どのファイルにも設定されていません。/etc/cron*
$ grep PATH /etc/cron* /etc/cron*/*
grep: /etc/cron.d: Is a directory
grep: /etc/cron.daily: Is a directory
grep: /etc/cron.hourly: Is a directory
grep: /etc/cron.monthly: Is a directory
grep: /etc/cron.weekly: Is a directory
/etc/cron.d/0hourly:PATH=/sbin:/bin:/usr/sbin:/usr/bin
それでは、cronユーザーcrontabセットのデフォルトのPATHはどこにありますか?独自にハードコードされていますかcron
?これに関する一種の設定ファイルを読みませんか?
答え1
ハードコードされています。ソースコード(このリンクは現在Debianへのものですcron
- さまざまな実装を考えると、cron
1つを選択するのは難しいですが、他のものも似ています):
#ifndef _PATH_DEFPATH
# define _PATH_DEFPATH "/usr/bin:/bin"
#endif
cron
デフォルトパスは設定ファイルから読み込まれません。その理由は、すでにすべてのcronjobで使用されているパス指定をサポートしているため、PATH=
他の場所でデフォルトを指定する必要がないためです。 (ハードコーディングされたデフォルト値を使用する作業項目のパスを指定する他の項目がない場合.)
答え2
PATH
Stephen Kittの回答に加えて、Ubuntuでcronを設定するための設定ファイルがあります。cron
無視するハードコーディングされたデフォルト値を使用しますPATH
(またはPATH
crontab自体で設定します)。ファイルは/etc/environment
.Note cron
PAMの設定です。
$ cat /etc/pam.d/cron
...
# Read environment variables from pam_env's default files, /etc/environment
# and /etc/security/pam_env.conf.
session required pam_env.so
# In addition, read system locale information
session required pam_env.so envfile=/etc/default/locale
...
これは確認が簡単です。/etc/environment
たとえば、変数を追加してfoo=bar
cronjobとして実行し、出力に表示される内容を確認します。env > /tmp/foo
foo=bar
しかし、なぜ?デフォルトのシステムフルパスは/ etc / profileに設定されていますが、他のディレクトリも含まれています。
$ grep PATH= /etc/profile PATH="/usr/local/sbin:/usr/local/bin:/usr/bin"
これはArch Linuxでは本当ですが、Ubuntuではデフォルト設定が 。ファイルが既存のファイルに追加されるPATH
ことです。/etc/environment
/etc/profile.d
PATH
~/.pam_environment
アーチモーション関連のバグ。
残念ながら、/etc/pam.d/cron
読み取りは含まれません~/.pam_environment
。奇妙なことは、/etc/pam.d/atd
する次のファイルが含まれます。
$ cat /etc/pam.d/atd
#
# The PAM configuration file for the at daemon
#
@include common-auth
@include common-account
session required pam_loginuid.so
@include common-session-noninteractive
session required pam_limits.so
session required pam_env.so user_readenv=1
...しかし、渡されたコマンドは、明らかat
にタスクが作成されたときに利用可能な環境を継承しますat
(たとえば、env -i /usr/bin/at ...
きれいな環境でタスクを実行しているように見えます)。
/etc/pam.d/cron
hasを修正してもuser_readenv=1
何も起こらないようで、 の変数も~/.pam_environment
大丈夫になり始めます(PATH
もちろんは除く)。
全体として、cronの環境変数を設定するのは面倒です。最高の場所は作業仕様自体のようです。これは、継承された環境変数cronがソースコードを読み取らずに無視することを決定できるかどうかわからないためです。