PATH ของ cron ตั้งอยู่ที่ไหน?


34

Cron ไม่ได้ใช้เส้นทางของผู้ใช้ที่เป็น crontab และมีของตัวเองแทน มันสามารถเปลี่ยนแปลงได้อย่างง่ายดายโดยการเพิ่มPATH=/foo/barที่จุดเริ่มต้นของ crontab และวิธีแก้ปัญหาแบบคลาสสิกคือการใช้เส้นทางที่แน่นอนไปยังคำสั่งที่เรียกใช้โดย cron แต่เส้นทางที่กำหนดไว้เริ่มต้นของ cron อยู่ที่ไหน?

ฉันสร้าง crontab พร้อมเนื้อหาต่อไปนี้ในระบบ Arch (cronie 1.5.1-1) และทดสอบบนกล่อง 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

ดังนั้น PATH ของ cron เริ่มต้นสำหรับ crontabs ผู้ใช้จะถูกตั้งอยู่ที่ไหน? มันเป็นฮาร์ดโค้ดในcronตัวของมันเองเหรอ? มันไม่ได้อ่านไฟล์กำหนดค่าบางอย่างสำหรับสิ่งนี้ใช่ไหม


3
ไม่มีเหตุผลที่cronจะต้องดู/etc/profileหรือใส่ใจเกี่ยวกับเปลือกหอยใด ๆ คำถามที่ดีกว่าคือทำไมไม่cronอ่านPATHจากlogin.defs(บน Linux) หรือlogin.conf(บน * BSD) ฉันคิดว่ามันเป็นรายละเอียดการใช้งานในท้ายที่สุด
Satō Katsura

@ SatōKatsuraแน่นอนฉันพูดถึงเพียง/etc/profileเพราะมันใช้ไวยากรณ์เดียวกัน ( var=value) เป็นcronตัวเองดังนั้นมันจะง่ายพอที่จะทำและ/etc/profileเป็นที่รู้ของฉันอย่างกว้างขวางมาก สิ่งที่ทำให้ฉันประหลาดใจคือฉันไม่สามารถหาได้ว่าตั้งไว้ที่ไหน ตามที่สตีเฟ่นอธิบายไว้ด้านล่าง
terdon

ผู้ใช้ที่ใช้zshเป็นเชลล์แบบโต้ตอบไม่สนใจ/etc/profile(ซึ่งเฉพาะเจาะจงbash)
Basile Starynkevitch

2
@BasileStarynkevitch ไม่มันไม่เฉพาะเจาะจงในการทุบตี เลย ! ค่อนข้างตรงกันข้าม! ในขณะที่มีเชลล์บางตัวที่ไม่อ่าน (c-shell family AFAIK), zsh ไม่ใช่หนึ่งในนั้น ดู manpage ของ zsh ถ้าคุณไม่เชื่อฉัน ไม่ว่าในกรณีใดเชลล์แบบโต้ตอบจะไม่เกี่ยวข้องเนื่องจากprofileไฟล์ต่างๆนั้นจะถูกอ่านโดยล็อกอินเชลล์เท่านั้น สิ่งเหล่านี้อาจหรืออาจไม่สามารถโต้ตอบได้
terdon

1
บางครั้งการทำงานstringsกับโปรแกรมสามารถช่วยค้นหาค่าที่กำหนดรหัสยากเหล่านี้ได้เช่นกัน
jrw32982 รองรับ Monica

คำตอบ:


47

มันเป็นรหัสยากในซอร์สโค้ด (ลิงก์นั้นชี้ไปที่ Debian ปัจจุบันcron- เนื่องจากความหลากหลายของcronการใช้งานมันยากที่จะเลือกอย่างใดอย่างหนึ่ง แต่การใช้งานอื่น ๆ ที่คล้ายกัน):

#ifndef _PATH_DEFPATH
# define _PATH_DEFPATH "/usr/bin:/bin"
#endif

#ifndef _PATH_DEFPATH_ROOT
# define _PATH_DEFPATH_ROOT "/usr/sbin:/usr/bin:/sbin:/bin"
#endif

cronไม่อ่านเส้นทางเริ่มต้นจากไฟล์กำหนดค่า; ฉันคิดว่าเหตุผลที่มันสนับสนุนการระบุเส้นทางที่ใช้อยู่แล้วPATH=ใน cronjob ใด ๆ ดังนั้นจึงไม่จำเป็นต้องระบุค่าเริ่มต้นที่อื่น (ค่าเริ่มต้นฮาร์ดโค้ดจะถูกใช้หากไม่มีสิ่งใดระบุพา ธ ในรายการงาน )


โปรดทราบว่าแม้จะมีการดำรงอยู่ของที่_PATH_DEFPATH_ROOTกำหนดผมได้รับการยืนยัน (ใช้งาน cron ของecho $PATH > /testfile) หลังจากแก้ไข crontab รากของใช้crontab -eใน Debian ยืดที่ crontab รากยังใช้_PATH_DEFPATHคือ "/ usr / bin: / bin" _PATH_DEFPATH_ROOT ไม่ได้ นี่เป็นการยืนยันโดยลิงก์ซอร์สโค้ดที่สองในคำตอบนี้ (ซึ่ง_PATH_DEFPATH_ROOTไม่ได้ใช้) ยังไม่ชัดเจนสำหรับฉันว่าคำจำกัดความเด็กกำพร้านี้เป็นข้อผิดพลาดหรือไม่
njahnke

8

เมื่อเพิ่มคำตอบของ Stephen Kitt มีไฟล์กำหนดค่าที่กำหนดPATHให้ cron บน Ubuntu และcron ไม่สนใจว่าPATHจะใช้ค่าเริ่มต้นที่กำหนดค่าตายตัว (หรือPATHตั้งค่าใน crontabs ด้วยตนเอง) /etc/environmentไฟล์ที่ได้คือ การ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เรียกใช้env > /tmp/fooเป็น cronjob และดูตามที่foo=barแสดงในเอาต์พุต


แต่ทำไม พา ธ ทั้งระบบดีฟอลต์ถูกตั้งค่าไว้ใน / etc / profile แต่มีไดเร็กทอรีอื่น:

$ grep PATH= /etc/profile
PATH="/usr/local/sbin:/usr/local/bin:/usr/bin"

ที่จริงใน Arch Linux แต่ในอูบุนตู, ฐานตั้งอยู่ใน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จะมีuser_readenv=1น่าจะก่อให้เกิดปัญหาใด ๆ และตัวแปรในการ~/.pam_environmentปรับเริ่มปรากฏขึ้น (ยกเว้นPATHของหลักสูตร)


ทั้งหมดบอกว่าการตั้งค่าตัวแปรสภาพแวดล้อมสำหรับ cron ดูเหมือนจะเป็นเรื่องยุ่ง สถานที่ที่ดีที่สุดดูเหมือนจะอยู่ในสเปคงานเองถ้าเพียงเพราะคุณไม่ทราบว่าตัวแปรสภาพแวดล้อมที่สืบทอดมา cron อาจตัดสินใจเพิกเฉย (โดยไม่ต้องอ่านแหล่งที่มา)


เกี่ยวกับatงานหากคุณถ่ายโอนatงานคุณจะเห็นว่างานนั้นตั้งสภาพแวดล้อมให้ตรงกับสภาพแวดล้อมเมื่อสร้างงาน
สตีเฟ่น Kitt
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.