Cron: รับข้อผิดพลาดในอีเมลเท่านั้นหรือ


38

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

เป็นไปได้หรือไม่ที่จะให้ CRON ส่งอีเมลเมื่อเกิดข้อผิดพลาดเช่น ของฉันTARไม่ทำงานตามที่ตั้งใจไว้?

นี่คือวิธีการตั้งค่า crontab ของฉันในขณะนี้;

0 */2 * * * /bin/backup.sh 2>&1 | mail -s "Backup status" email@example.com

ขอบคุณมาก!

คำตอบ:


53

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

MAILTO=email@example.com
0 */2 * * * /bin/backup.sh

หากสคริปต์ของคุณสร้างเอาต์พุตปกติ แต่คุณไม่สนใจมันใน cron เพียงส่งไปที่ / dev / null และมันจะส่งอีเมลถึงคุณเมื่อมีบางสิ่งที่เขียนถึง stderr

MAILTO=email@example.com
0 */2 * * * /bin/backup.sh > /dev/null

9
นี่คืออุดมคติที่แทบจะไม่ โดยทั่วไปคุณต้องการเอาต์พุตทั้งหมด (stdout + stderr) ส่งอีเมลถึงคุณเมื่อคำสั่งลงท้ายด้วยรหัสข้อผิดพลาดที่ไม่เป็นศูนย์ มิฉะนั้นจะดีกว่าที่จะฮุบอย่างน้อย stdout สำหรับฉันนี่คือข้อบกพร่องในการออกแบบของ cron
Witiko

3
@Witiko ฉันเห็นด้วย; ฉันพบคำถามนี้พยายามแก้ไขปัญหานั้น ฉันเดาว่าคุณสามารถใช้คำสั่ง cron ของคุณ/bin/backup.sh > log_file || (echo Backup failed with exit status $?; cat log_file)?
Daniel H

22

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

แทน:

 0 1 * * * /bin/backup.sh 2>&1 | mail -s "Backup status" email@example.com

ทำ:

 MAILTO=email@example.com
 0 1 * * * cronic /bin/backup.sh

ใส่เพียง; มันจะทำงานเงียบหากทุกอย่างทำงานราบรื่น (สถานะออก 0) แต่มันจะรายงานอย่างละเอียดถ้าไม่และให้ cron จัดการการรายงานจดหมาย

ข้อมูลเพิ่มเติมเกี่ยวกับhttps://habilis.net/cronic/


ฉันไม่เห็นว่ามันจะช่วยได้อย่างไรเมื่อปัญหาไม่มีอะไรมากไปกว่า cron line ที่ไม่ถูกต้องและ cron กำลังทำสิ่งที่มันบอกให้ทำ
John Gardeniers

3
@JohnGardeniers ช่วยได้เพราะบางครั้งคุณมีเอาต์พุตโดยไม่มีข้อผิดพลาด
มิคาอิล

11
อีกทางเลือกหนึ่งchronicจากmoreutilsแพคเกจ: joeyh.name/code/moreutils
Vladimir Panteleev

4

คุณกำลังสอนโดยเฉพาะcronให้ส่งอีเมลเสมอแม้ว่า/bin/backup.shจะ/usr/local/binประสบความสำเร็จก็ตาม เพียงละเว้น| mail -s "Backup status" email@example.comส่วนหนึ่งและอีเมลจะถูกส่งเมื่อมีเอาต์พุตเท่านั้น คุณสามารถcronตั้งค่าที่อยู่อีเมลเป็นเมลที่กำหนดในไฟล์ crontab ได้อย่างชัดเจน(ขึ้นอยู่กับของคุณ)

สำหรับรายละเอียดโปรดดู

man 5 crontab

3

คุณควรจะกำกับstderranmd ไม่ใช่ทั้งสองอย่างและstdoutstderr

ใช้1> /dev/nullไม่ได้2>&1และควรจะใช้ได้ นอกจากนี้คุณอาจต้องรายงานข้อผิดพลาดอย่างถูกต้องในสคริปต์สำรองของคุณ


3

นี่คือรูปแบบอื่นที่ฉันใช้สำเร็จมาหลายปีแล้ว - จับเอาท์พุทและพิมพ์ออกมาโดยมีข้อผิดพลาดเท่านั้นทำให้เกิดอีเมล นี้ไม่จำเป็นต้องไฟล์ temp และเก็บรักษาผลผลิตทั้งหมด ส่วนที่สำคัญคือการ2>&1เปลี่ยนเส้นทาง STDERR ไปยัง STDOUT

ส่งเอาต์พุตทั้งหมดผ่านการกำหนดค่า cron mailer ที่เป็นค่าเริ่มต้น:

1 2 * * * root OUTPUT=`flexbackup -set all 2>&1` || echo "$OUTPUT"

เหมือนกัน แต่มีที่อยู่เฉพาะและหัวเรื่อง:

(ที่อยู่สามารถเปลี่ยนแปลงได้โดยการตั้งค่าMAILTO = xxxxสำหรับไฟล์ crontab ทั้งหมด)

1 2 * * * root OUTPUT=`flexbackup -set all 2>&1` || echo "$OUTPUT" | mail -s "Failed to backup" an@email.address

คุณสามารถดำเนินการหลายอย่างพร้อมกันเมื่อเกิดข้อผิดพลาดและเพิ่มไปยังอีเมล:

1 2 * * * root OUTPUT=`flexbackup -set all 2>&1` || {echo "$OUTPUT" ; ls -ltr /backup/dir ; }

สิ่งนี้จะทำงานกับคำสั่งง่าย ๆ หากคุณกำลังจัดการกับ pipes ที่ซับซ้อน ( find / -type f | grep -v bla | tar something-or-other) คุณควรย้ายคำสั่งไปยังสคริปต์และเรียกใช้สคริปต์โดยใช้วิธีการดังกล่าวข้างต้น เหตุผลก็คือถ้าส่วนใดส่วนหนึ่งของไพพ์ส่งออกไปยัง STDERR คุณจะยังคงได้รับอีเมล

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