Cron tidak menggunakan jalur dari pengguna yang memiliki crontab itu dan, sebaliknya, memiliki sendiri. Ini dapat dengan mudah diubah dengan menambahkan PATH=/foo/bar
di awal crontab, dan solusi klasiknya adalah selalu menggunakan path absolut untuk perintah yang dijalankan oleh cron, tetapi di mana PATH default cron didefinisikan?
Saya membuat crontab dengan konten berikut pada sistem Arch saya (cronie 1.5.1-1) dan juga diuji pada kotak Ubuntu 16.04.3 LTS dengan hasil yang sama:
$ crontab -l
* * * * * echo "$PATH" > /home/terdon/fff
Itu dicetak:
$ cat fff
/usr/bin:/bin
Tapi kenapa? Jalur lebar sistem default ditetapkan /etc/profile
, tetapi itu termasuk direktori lain:
$ grep PATH= /etc/profile
PATH="/usr/local/sbin:/usr/local/bin:/usr/bin"
Tidak ada hal lain yang relevan dalam /etc/environment
atau /etc/profile.d
, file lain yang saya pikir mungkin dapat dibaca oleh 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
Ada juga tidak ada yang relevan di salah satu file /etc/skel
, tidak mengejutkan, juga tidak diatur dalam /etc/cron*
file apa pun :
$ 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
Jadi, di mana PATH default cron untuk crontab pengguna disetel? Apakah hardcode cron
itu sendiri? Bukankah itu membaca semacam file konfigurasi untuk ini?
cron
melihat/etc/profile
, atau peduli dengan cangkang tertentu. Pertanyaan yang lebih baik adalah mengapa tidakcron
membacaPATH
darilogin.defs
(di Linux) ataulogin.conf
(di * BSD). Saya kira itu akhirnya merupakan detail implementasi./etc/profile
karena menggunakan sintaks yang sama (var=value
) seperticron
itu sendiri, jadi itu akan cukup mudah untuk dilakukan dan/etc/profile
, setahu saya, sangat luas. Yang mengejutkan saya adalah bahwa saya tidak dapat menemukannya diatur di mana saja sehingga tampak seperti itu sulit dikodekan. Memang benar, seperti yang dijelaskan Stephen di bawah ini.zsh
sebagai shell interaktif mereka tidak peduli/etc/profile
(yang khusus untukbash
)profile
file hanya dibaca oleh shell login. Ini mungkin, atau mungkin tidak interaktif.strings
melawan suatu program dapat membantu menemukan nilai-nilai ini juga.Jawaban:
Hard-coded dalam kode sumber (yang menunjukkan poin ke Debian saat ini
cron
- mengingat beragamcron
implementasi, sulit untuk memilih satu, tetapi implementasi lain mungkin serupa):cron
tidak membaca jalur default dari file konfigurasi; Saya membayangkan alasan ada yang mendukung menentukan jalur yang sudah digunakanPATH=
dalam cronjob, jadi tidak perlu untuk dapat menentukan default di tempat lain. (Default hard-coded digunakan jika tidak ada yang lain yang menentukan jalur dalam entri pekerjaan .)sumber
_PATH_DEFPATH_ROOT
define, saya mengkonfirmasi (menggunakan cron jobecho $PATH > /testfile
) setelah mengedit crontab root menggunakancrontab -e
pada Debian Stretch yang juga menggunakan crontab root_PATH_DEFPATH
, yaitu "/ usr / bin: / bin", tidak_PATH_DEFPATH_ROOT
. Ini juga dikonfirmasi oleh tautan kode sumber kedua dalam jawaban ini (yang_PATH_DEFPATH_ROOT
tidak digunakan). Tidak jelas bagi saya apakah definisi yatim ini adalah bug.Menambah jawaban Stephen Kitt, ada file konfigurasi yang set
PATH
untuk cron pada Ubuntu, dancron
pengabaian yangPATH
menggunakan default keras-kode (atauPATH
s diatur dalam crontab sendiri). File tersebut adalah/etc/environment
.cron
Konfigurasi PAM Note :Ini mudah diverifikasi. Tambahkan variabel ke
/etc/environment
, katakanlahfoo=bar
, jalankanenv > /tmp/foo
sebagai cronjob dan tonton seperti yangfoo=bar
ditampilkan di output.Itu benar di Arch Linux, tetapi di Ubuntu, basis
PATH
sudah diatur/etc/environment
. File di/etc/profile.d
pakukan ke yang sudah adaPATH
, dan Anda dapat menambahkannya di~/.pam_environment
. Saya memiliki bug yang diajukan tentang perilaku Arch .Sayangnya,
/etc/pam.d/cron
tidak termasuk membaca dari~/.pam_environment
. Anehnya,/etc/pam.d/atd
memang termasuk file itu:... tetapi perintah yang dijalankan
at
tampaknya mewarisi lingkungan yang tersedia saat membuatat
pekerjaan (misalnya,env -i /usr/bin/at ...
tampaknya menjalankan pekerjaan dengan lingkungan yang sangat bersih).Mengubah
/etc/pam.d/cron
memilikiuser_readenv=1
tampaknya tidak menimbulkan masalah, dan variabel di~/.pam_environment
mulai muncul baik (kecuali untukPATH
, tentu saja).Semua mengatakan, menetapkan variabel lingkungan untuk cron tampaknya menjadi bisnis yang berantakan. Tempat terbaik tampaknya berada dalam spesifikasi pekerjaan itu sendiri, jika hanya karena Anda tidak tahu variabel lingkungan bawaan mana yang mungkin diabaikan oleh cron (tanpa membaca sumbernya).
sumber
at
pekerjaan, jika Anda membuang suatuat
pekerjaan Anda akan melihatnya secara eksplisit mengatur lingkungan agar sesuai dengan lingkungan ketika pekerjaan itu dibuat.