Cron không sử dụng đường dẫn của người dùng có crontab và thay vào đó, có đường dẫn riêng. Nó có thể dễ dàng thay đổi bằng cách thêm PATH=/foo/bar
vào đầu crontab và cách giải quyết cổ điển là luôn luôn sử dụng các đường dẫn tuyệt đối đến các lệnh được chạy bởi cron, nhưng PATH mặc định của cron được định nghĩa ở đâu?
Tôi đã tạo một crontab với các nội dung sau trên hệ thống Arch của tôi (cronie 1.5.1-1) và cũng đã thử nghiệm trên hộp Ubuntu 16.04.3 LTS với kết quả tương tự:
$ crontab -l
* * * * * echo "$PATH" > /home/terdon/fff
Nó được in:
$ cat fff
/usr/bin:/bin
Nhưng tại sao? Đường dẫn toàn hệ thống mặc định được đặt /etc/profile
, nhưng bao gồm các thư mục khác:
$ grep PATH= /etc/profile
PATH="/usr/local/sbin:/usr/local/bin:/usr/bin"
Không có gì khác có liên quan trong /etc/environment
hoặc /etc/profile.d
, các tệp khác mà tôi nghĩ có thể được đọc bởi 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
Không có gì có liên quan trong bất kỳ tệp nào trong /etc/skel
, không ngạc nhiên, cũng không được đặt trong bất kỳ /etc/cron*
tệp nào :
$ 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
Vậy, PATH mặc định của cron cho crontabs của người dùng được đặt ở đâu? Có phải nó được mã hóa cứng trong cron
chính nó? Nó không đọc một số loại tập tin cấu hình cho điều này?
/etc/profile
vì nó sử dụng cùng một cú pháp ( var=value
) như cron
chính nó, vì vậy nó sẽ đủ dễ để làm và /etc/profile
, theo hiểu biết của tôi, rất phổ biến. Điều làm tôi ngạc nhiên là tôi không thể tìm thấy nó được đặt ở bất cứ đâu nên có vẻ như nó được mã hóa cứng. Thực sự là như vậy, như Stephen giải thích dưới đây.
zsh
làm vỏ tương tác của họ không quan tâm /etc/profile
(cụ thể là bash
)
profile
tệp khác nhau chỉ được đọc bởi shell đăng nhập. Đây có thể, hoặc có thể không tương tác.
strings
với một chương trình cũng có thể giúp tìm thấy các giá trị được mã hóa cứng này.
cron
để xem xét/etc/profile
, hoặc quan tâm đến bất kỳ vỏ cụ thể. Một câu hỏi hay hơn là tại sao khôngcron
đọcPATH
từlogin.defs
(trên Linux) hoặclogin.conf
(trên * BSD). Tôi cho rằng cuối cùng nó là một chi tiết thực hiện.