วิธีตั้งค่างานรูต cron อย่างถูกต้อง


35

ฉันพยายามตั้งค่างานรูท cron เพื่อรันสคริปต์ Bash ในฐานะรูทเพื่อรันที่ 7,37 นาทีทุกชั่วโมงทุกวันทุกเดือนทุกเดือน สคริปต์นี้ตั้งอยู่และตั้งชื่อ/usr/bin tunlrupdate.shมันอัปเดต DNS ของ Tunlr

$ ls -l /usr/bin/tunlrupdate.sh 
-rwxr-xr-x 1 root root 2133 Sep 24 15:42 /usr/bin/tunlrupdate.sh

สคริปต์ทุบตีนี้สามารถใช้ได้ที่นี่

เมื่อเรียกใช้สคริปต์จะเขียนสิ่งที่เกิดขึ้นในบันทึกที่อยู่ใน /var/log/tunlr.log

ในการเพิ่มงาน cron รูทนี้ฉันใช้มาตรฐานสำหรับ crontab ของรูท

sudo crontab -e

และแทรกสองบรรทัดเหล่านี้ในตอนท้าย ฉันคาดว่า cron จะเรียกใช้สคริปต์เป็น root

# check for updated Tunlr DNS every 30 minutes at the hour + 7 mn and hour + 37 mn
07,37 * * * * root /usr/bin/tunlrupdate.sh

คำสั่งในภายหลังsudo crontab -lยืนยันว่ามีการแทรกงาน cron

ฉันรีบูท Ubuntu และกำลังตรวจสอบไฟล์บันทึกถ้างาน cron เปิดใช้งานอย่างถูกต้อง อย่างไรก็ตามไม่มีสิ่งใดในล็อกไฟล์/var/log/tunlr.logหมายความว่างานไม่เคยเปิดตัวได้สำเร็จ

ฉันตรวจสอบว่าถ้าฉันเรียกใช้สคริปต์จากบรรทัดคำสั่ง

sudo /usr/bin/tunlrupdate.sh

จากนั้นไฟล์บันทึกการทำงานจะได้รับการอัพเดตตามนั้น

เหตุใดงาน cron นี้ไม่ทำงานตามที่วางแผนไว้ในระบบของฉัน

อัปเดต 1: โซลูชันที่เสนอทั้งหมดจนถึงไม่สามารถใช้งานได้ ผมขอขอบคุณสำหรับ Olli CLI sudo grep CRON /var/log/syslogไปยังรายการบันทึกของระบบ อย่างไรก็ตามฉันได้รับข้อผิดพลาด CRON

CRON[13092]: (root) CMD (  [ -x /usr/lib/php5/maxlifetime ] && [ -d /var/lib/php5 ]
&& find /var/lib/php5/ -depth -mindepth 1 -maxdepth 1 -type f -cmin +$(/usr/lib/php
/maxlifetime) ! -execdir fuser -s {} 2>/dev/null \; -delete)

ด้วยการแนะนำ PATH = การแทรก & การใช้พา ธ สัมบูรณ์จากรูทสำหรับฟังก์ชั่นในสคริปต์หรือไม่มีวิธีแก้ปัญหาที่แนะนำนี้ที่นี่ ฉันยังคงได้รับข้อผิดพลาดนี้

หลังจากค้นหาบางฉันพบข้อผิดพลาดในไฟล์/usr/lib/php5/maxlifetimeตามที่อธิบายไว้ที่นี่ :Change #!/bin/sh -e --> #!/bin/sh -x

จากนั้นแสดงรายการบันทึกข้อผิดพลาด CRON ในระบบของฉัน

sudo grep CRON /var/log/syslog
Feb 11 18:07:01 Marius-PC CRON[14067]: (root) CMD (root /usr/bin/tunlrupdate.sh)
Feb 11 18:07:01 Marius-PC CRON[14066]: (root) MAIL (mailed 1 byte of output; but got
status 0x00ff, #012)

ฉันยังไม่ได้รับสคริปต์ bash ที่กำลังเรียกใช้งาน เวลานี้ไม่มีข้อผิดพลาดแสดงในบันทึก เพื่อให้ได้ความมั่นใจนี่ไม่ใช่เนื้อหาของสคริปต์ฉันลดสคริปต์เป็น 3 บรรทัดต่อไปนี้:

#!/bin/bash
LOGFILE=/var/log/tunlr.log
echo $LOGFILE >> $LOGFILE

ฉันยังไม่ได้งาน cron ผ่าน ไม่มีสิ่งใดเขียนในไฟล์บันทึก ดังนั้นแม้อาจเป็นสคริปต์ว่างเปล่าจะไม่ทำงานใน cron? ฉันไม่เข้าใจ ฉันรู้ว่าการลองใช้สคริปต์ลดเหลือ 2 บรรทัดนี้:

#!/bin/bash
exit 0

และยังคงบันทึกข้อผิดพลาดเดียวกัน สคริปต์ cron ไม่ผ่าน ...


ถ้าคุณต้องการให้ cronjob "รูท" คุณต้องรูทจากนั้นคุณพิมพ์ crontab -e นอกจากนี้คุณเพียงแค่ต้องเข้าสู่ระบบในฐานะ root (ประเภทคอนโซล "su root") จากนั้น crontab -e (ไม่จำเป็นต้องใช้ sudo ในกรณีนี้)
Wolfgang

ดี. ฉันไม่เห็นประเด็นคำตอบของคุณ? การพิมพ์ $ sudo crontab -e ทำงานตามที่รายงานโดย $ sudo crontab -l เช่นบรรทัดที่อธิบายงานใหม่ได้ถูกเพิ่มลงใน cron ของรูท ตามที่ระบุงานจะไม่ปรากฏใน cron ผู้ใช้เช่น $ crontab -l ไม่แสดงงาน cron ใด ๆ ที่ถูกเพิ่มที่นี่
อันโตนิโอ

@ WolfgangVogl เขาใช้ "sudo" ซึ่งทำงานได้ตามที่คาดไว้
Alexis Wilke

คำตอบ:


68

หากคุณต้องการเรียกใช้สคริปต์ในฐานะผู้ใช้ปกติ :

crontab -e

และเพิ่มบรรทัด:

07,37 * * * * /usr/bin/tunlrupdate.sh

หากคุณต้องการเรียกใช้สคริปต์เป็นรูท :

sudo crontab -e

และเพิ่มบรรทัดเดียวกัน:

07,37 * * * * /usr/bin/tunlrupdate.sh

@NineCattoRules ถ้าคุณไม่ทำเอาท์พุตคุณเห็นอะไร?
Angelo Fuchs

@AngeloFuchs ความคิดเห็นเก่า ... แน่นอนฉันลองใช้คำสั่งนั้นในฐานะรูท ( sudo crontab -eแทนcrontab -e) หรืออย่างอื่นก็ใช้งานได้
NineCattoRules

10

ในที่สุดการแก้ปัญหาการทำงาน ใน syslog ฉันเห็นการซ้ำซากและน่าสนใจ:

CRON[18770]: (root) CMD (root /usr/bin/tunlrupdate.sh)

ฟังดูเหมือนรูทไม่ได้รับการยอมรับว่าเป็นคำสั่ง ขณะที่ผมใช้อยู่แล้ว cron $ sudo /usr/bin/tunlrupdate.shรากโดยใช้ จากนั้นฉันลองใช้สคริปต์ต้นฉบับ (แก้ไขข้อผิดพลาดในวันที่ UNIX cmd:% m ซึ่งใช้เดือนเป็นนาทีซึ่งก็คือ% M) ต่อไปนี้ (ซึ่งลบรากออกจาก cron line):

$ sudo crontab -e
# check for updated Tunlr DNS every 30 minutes at the hour + 7 mn and hour + 37 mn
07,37 * * * * /usr/bin/tunlrupdate.sh

สิ่งนี้กลายเป็นทางออกสุดท้าย [แม้ว่าฉันจะพบคะแนนวรรณกรรมที่ระบุถึงบรรทัดที่ผิดพลาดพร้อมกับรูตในบรรทัด cron นั่นเป็นความผิดพลาด]


จุดที่ดี Olli ฉันเห็นด้วยกับคุณในเรื่องนั้น สำหรับการอ้างอิงผู้ใช้ crontab จะถูกเก็บไว้ใน / var / spool / cron / crontabs / ชื่อผู้ใช้หรือสำหรับ root / var / spool / cron / crontabs / root ดูหน้านี้askubuntu.com/questions/216692/where-is-the-user-crontab-storedโฟลเดอร์ที่มีอยู่แล้วเป็นชื่อของผู้ใช้
อันโตนิโอ

คุณไม่ควรต้องการข้อมูลนี้เนื่องจากคุณควรแก้ไขไฟล์ crontab ด้วยcrontabคำสั่ง (ยกเว้นไฟล์ crontab ด้านล่าง/etc)
Olli

1
@ อันโตนิโอคะแนนที่มีฟิลด์ชื่อผู้ใช้จะใช้เฉพาะใน/etc/crontab(crontab ทั้งระบบ) การใช้งานsudo crontab -eคุณกำลังทำงานกับ crontab ของรูทซึ่งมักพบได้ใน/var/spool/cron/crontabs
Matijs

2

"ปัญหา" อย่างหนึ่งของ cron คือการขาดตัวแปรสภาพแวดล้อม (เพื่อเหตุผลด้านความปลอดภัยที่ชัดเจน ) คุณอาจหลงทาง PATH และ HOME คุณสามารถกำหนดสิ่งเหล่านั้นในสคริปต์โดยตรงหรือในไฟล์ crontab

# check for updated Tunlr DNS every 30 minutes at the hour + 7 mn and hour + 37 mn
PATH=/usr/bin
07,37 * * * * root /usr/bin/tunlrupdate.sh

คุณจะต้องทดสอบจนกว่าตัวแปรที่จำเป็นทั้งหมดจะถูกกำหนดตามที่สคริปต์ต้องการ


1
นี่เป็นคำตอบเดียวที่นี่ที่ใช้งานได้จริงสำหรับฉัน ฉันคัดลอกคำสั่ง SHELL และ PATH จาก/etc/crontabไฟล์และวางลงในsudo crontab -eและคำสั่งรันเป็นรูทโดยไม่มีปัญหา ขอขอบคุณ!
Terrance

0

ข้อความแสดงข้อผิดพลาด Cron มักจะ - โดยค่าเริ่มต้น - ส่งทางอีเมล คุณสามารถตรวจสอบว่ามีอีเมลสำหรับรากsudo mailหรือโดยเพียงแค่การตรวจสอบเนื้อหาเช่น/var/mail/rootsudo less /var/mail/root


หากข้อความอีเมลไม่ช่วยให้ตรวจสอบด้วย/var/log/syslog:

sudo grep CRON /var/log/syslog

อย่างที่ Alexis Wilke พูดไปแล้ว cron มีกลไกที่แตกต่างกันสำหรับการตั้งค่าตัวแปรสภาพแวดล้อม

สคริปต์ของคุณต้องการ

PATH=/sbin:/bin:/usr/bin

ไปที่ crontab HOMEไม่ควรจำเป็น คุณควรใช้เส้นทางที่แน่นอนในสคริปต์ของคุณเช่นแทน/bin/date dateคุณสามารถค้นหาเส้นทางที่เหมาะสมสำหรับแต่ละคำสั่งด้วย which command_nameเช่น

$ which date
/bin/date

ใช้ grep CRON ที่คุณแนะนำใน / var / log / syslog ฉันได้รับคนโง่ Feb 11 14:37:01 Marius-PC CRON [7826]: (root) CMD (root /usr/bin/tunlrupdate.sh) 11 กุมภาพันธ์ 14: 37:01 Marius-PC CRON [7825]: (root) MAIL (ส่ง 1 ไบต์ของเอาต์พุต แต่มีสถานะ 0x00ff, # 012) 11 กุมภาพันธ์ 14:39:01 CRON Marius-PC [7849]: (root) CMD ( [-x / usr / lib / php5 / maxlifetime] && [-d / var / lib / php5] && ค้นหา / var / lib / php5 / -depth -mindepth 1 -maxdepth 1 -type f -cmin + $ (/ usr / lib / php5 / maxlifetime)! -execdir fuser -s {} 2> / dev / null \; -delete) หากฉันเพิ่มคำจำกัดความของ PATH ใน cron สิ่งเหล่านี้จะไม่ส่งผลกระทบต่อระบบของฉัน $ PATH?
อันโตนิโอ

ผลลัพธ์นั้นบอกว่าพยายามส่งอีเมลถึงบางอย่าง แต่ล้มเหลว หมายความว่าคุณไม่ได้รับข้อความแสดงข้อผิดพลาด/var/mail/rootนั้น คุณสามารถแก้ไขได้หรือลองกับPATH=...
Olli


ขอบคุณ ฉันรู้ว่าฉันไม่ได้กำหนดค่าอีเมลของระบบและทราบว่าไม่ผ่าน ฉันได้ปรับเปลี่ยนสคริปต์เพื่อใช้เส้นทางที่แน่นอนสำหรับฟังก์ชันใด ๆ ที่เรียกว่า สิ่งสุดท้ายคือคำถามก่อนหน้านี้คำจำกัดความ PATH ภายใน crontab จะไม่ทำให้ตัวแปร $ PATH ของระบบของฉันยุ่งเหยิง?
อันโตนิโอ

1
ในช่วงเวลาที่ฉันกำลังยุ่งแก้ไขข้อผิดพลาดในรูปแบบวันที่จากสคริปต์ต้นฉบับ ใช้% m (ซึ่งไม่ใช่เดือนไม่ใช่นาที) แทน% M ...
Antonio

0

คุณสามารถเพิ่มบรรทัดนี้ในสคริปต์ของคุณ ดังนั้นหลังจากที่คุณตรวจสอบบันทึก cron และประมวลผลงานของคุณแล้วคุณจะได้รับ $ PATH แบบเดียวกับที่ crontabs มี

/bin/echo $PATH > /root/path.txt

และสิ่งที่ดีที่สุดที่คุณสามารถทำได้เพื่อวินิจฉัยปัญหาในสคริปต์ cron คือรับตัวแปรสภาพแวดล้อมทั้งหมดของ SO ด้วยคำสั่ง env ในสคริปต์ของคุณ ดังนั้นเพียงเพิ่มบรรทัดนี้ในสคริปต์ของคุณ จากนั้นคุณสามารถวิเคราะห์ผลลัพธ์allEvnVars.txt

/usr/bin/env > /root/allEvnVars.txt

เคล็ดลับก็คือการส่งออกโดยตรงของสคริปต์ไปยังสถานที่บางแห่ง /root/log.logเพิ่ม วิธีนี้เอาต์พุตทั้งหมดของสคริปต์จะถูกคงไว้/root/log.log

07,37 * * * * root /usr/bin/tunlrupdate.sh  > /root/log.log

นอกจากนี้คุณยังสามารถกำหนดเวลาให้สคริปต์เรียกใช้แต่ละนาทีเพื่ออำนวยความสะดวกในการทดสอบและตรวจสอบ

*/1 * * * * root /usr/bin/tunlrupdate.sh  > /root/log.log
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.