เหตุใด crontab ของฉันไม่ทำงานและฉันจะแก้ไขปัญหาได้อย่างไร


225

นี่เป็นคำถามที่ยอมรับได้เกี่ยวกับการใช้ cron & crontab

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

คำตอบสำหรับ ' ทำไม crontab ของฉันไม่ทำงานและฉันจะแก้ไขปัญหาได้อย่างไร สามารถดูได้ด้านล่าง นี่คือที่อยู่cronระบบที่มี crontab เน้น



1
@DanDascalescu ดูเหมือนว่า Eric ต้องการตัวแทนมากขึ้น
ฉันเป็นคนที่โง่ที่สุดที่

1
ฉันเพิ่งเข้าร่วม Server Fault SE (เพียง 101 ตัวแทน) แต่ชอบที่จะให้คำถามนี้ -1 !! คำถามนี้สร้างขึ้นเพื่อรับตัวแทนเท่านั้นหรือไม่ @IamtheMostStupidPerson เห็นด้วยกับคุณโดยสิ้นเชิง ...
Holyprogrammer

อุดมการณ์ตะวันตกใน padawans อายุ 13 ปีเหล่านี้เป็นทั้งตำราและสิ่งที่ยอดเยี่ยมเหมือนซูเปอร์โนวา เพื่อตอบคำถามของคุณทั้งสอง: ใช่ฉันทำเพื่อตัวแทนและใช่ Eric ต้องการชื่อเสียงมากขึ้น ฉันต้องการตัวแทนมากแค่ไหน ?? มากกว่า. youtu.be/IaDt9T7BF38?t=262
Eric Leschinski

คำตอบ:


317

วิธีแก้ไข crontab ที่เกี่ยวข้องกับ woes / problems (Linux) ทั้งหมดของคุณ


นี่คือวิกิชุมชนถ้าคุณสังเกตเห็นสิ่งที่ไม่ถูกต้องกับคำตอบนี้หรือมีข้อมูลเพิ่มเติมโปรดแก้ไข


ก่อนคำศัพท์พื้นฐาน:

  • cron (8)เป็น daemon ที่ดำเนินการคำสั่งที่กำหนดไว้
  • crontab (1)เป็นโปรแกรมที่ใช้ในการแก้ไขไฟล์ผู้ใช้ crontab (5)
  • crontab (5)เป็นไฟล์สำหรับผู้ใช้ที่มีคำแนะนำสำหรับ cron (8)

ถัดไปการศึกษาเกี่ยวกับ cron:

ผู้ใช้ทุกคนในระบบอาจมีไฟล์ crontab ของตนเอง สถานที่ตั้งของรากและ crontab ใช้ไฟล์ที่มีขึ้นอยู่กับระบบ /var/spool/cronแต่พวกเขามักจะมีดังต่อไปนี้

มี/etc/crontabไฟล์ทั้งระบบ/etc/cron.dไดเรกทอรีอาจมีชิ้นส่วน crontab ซึ่งยังอ่านและดำเนินการโดย cron ลีนุกซ์ดิสทริบิวชันบางตัว (เช่น Red Hat) ยังมี/etc/cron.{hourly,daily,weekly,monthly}ไดเร็กตอรี่, สคริปต์ที่อยู่ข้างในซึ่งจะถูกประมวลผลทุกชั่วโมง / วัน / สัปดาห์ / เดือน, โดยมีสิทธิ์รูท

รูทสามารถใช้คำสั่ง crontab ได้ตลอดเวลา ผู้ใช้ทั่วไปอาจหรือไม่ได้รับอนุญาตให้เข้าถึง เมื่อคุณแก้ไขไฟล์ crontab ด้วยคำสั่งcrontab -eและบันทึก crond จะตรวจสอบความถูกต้องพื้นฐาน แต่ไม่รับประกันว่าไฟล์ crontab ของคุณจะเกิดขึ้นอย่างถูกต้อง มีไฟล์ชื่อcron.denyซึ่งจะระบุผู้ใช้ที่ไม่สามารถใช้ cron ได้ cron.denyตั้งไฟล์ขึ้นอยู่กับระบบและสามารถลบซึ่งจะช่วยให้ผู้ใช้ทุกคนที่จะใช้ cron

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

รายการ crontab, วิธีการกำหนดคำสั่ง:

คำสั่ง crontab แสดงโดยบรรทัดเดียว คุณไม่สามารถใช้\เพื่อขยายคำสั่งผ่านหลายบรรทัด เครื่องหมาย hash ( #) แสดงถึงความคิดเห็นซึ่งหมายความว่า cron จะไม่สนใจสิ่งใดในบรรทัดนั้น ช่องว่างนำหน้าและบรรทัดว่างจะถูกละเว้น

ระวังให้มากเมื่อใช้%เครื่องหมายเซ็นต์( ) ในคำสั่งของคุณ เว้นแต่ว่าพวกเขาจะหลบหนี\%พวกเขาจะถูกแปลงเป็นบรรทัดใหม่และทุกอย่างหลังจากที่ไม่มีการหลบหนีครั้งแรก%จะถูกส่งผ่านไปยังคำสั่งของคุณใน stdin

มีสองรูปแบบสำหรับไฟล์ crontab:

  • ผู้ใช้ crontabs

    # Example of job definition:
    # .---------------- minute (0 - 59)
    # |  .------------- hour (0 - 23)
    # |  |  .---------- day of month (1 - 31)
    # |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
    # |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7)
    # |  |  |  |  |
    # *  *  *  *  *   command to be executed
    
  • ระบบกว้าง/etc/crontabและ/etc/cron.dชิ้นส่วน

    # Example of job definition:
    # .---------------- minute (0 - 59)
    # |  .------------- hour (0 - 23)
    # |  |  .---------- day of month (1 - 31)
    # |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
    # |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7)
    # |  |  |  |  |
    # *  *  *  *  * user-name  command to be executed
    

ขอให้สังเกตว่าหลังต้องมีชื่อผู้ใช้ คำสั่งจะถูกเรียกใช้ในฐานะผู้ใช้ที่ระบุชื่อ

5 ฟิลด์แรกของบรรทัดแสดงเวลาที่ควรรันคำสั่ง คุณสามารถใช้หมายเลขหรือชื่อวัน / เดือนที่เกี่ยวข้องได้ในการระบุเวลา

  • เขตข้อมูลจะถูกคั่นด้วยช่องว่างหรือแท็บ
  • เครื่องหมายจุลภาค ( ,) ใช้เพื่อระบุรายการเช่น 1,4,6,8 ซึ่งหมายถึงเรียกใช้ที่ 1,4,6,8
  • ช่วงจะถูกระบุด้วยเครื่องหมายขีดกลาง ( -) และอาจรวมกับรายการเช่น 1-3,9-12 ซึ่งหมายถึงระหว่าง 1 ถึง 3 จากนั้นระหว่าง 9 ถึง 12
  • /ตัวละครที่สามารถนำมาใช้ในการแนะนำขั้นตอนเช่น 2/5 ซึ่งหมายถึงการเริ่มต้นที่ 2 แล้วทุก 5 (2,7,12,17,22 ... ) พวกเขาไม่ได้พันผ่านมา
  • เครื่องหมายดอกจัน ( *) ในฟิลด์หมายถึงช่วงทั้งหมดสำหรับฟิลด์นั้น (เช่น0-59สำหรับฟิลด์นาที)
  • สามารถรวมช่วงและขั้นตอนต่างๆได้เช่น*/2หมายถึงการเริ่มต้นที่ต่ำสุดสำหรับฟิลด์ที่เกี่ยวข้องจากนั้นทุก ๆ 2 เช่น 0 สำหรับนาที (0,2 ... 58), 1 สำหรับเดือน (1,3 ... 11) เป็นต้น

การดีบักคำสั่ง cron

ตรวจสอบอีเมล!

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

MAILTO=user@somehost.tld
1 2 * * * /path/to/your/command

จับเอาท์พุทด้วยตัวคุณเอง

คุณสามารถเปลี่ยนเส้นทาง stdout และ stderr ไปยังไฟล์ ไวยากรณ์ที่แน่นอนสำหรับการจับผลลัพธ์อาจแตกต่างกันไปขึ้นอยู่กับเชลล์ cron ที่ใช้ นี่คือตัวอย่างสองตัวอย่างที่บันทึกเอาต์พุตทั้งหมดไปยังไฟล์ที่/tmp/mycommand.log:

1 2 * * * /path/to/your/command &>/tmp/mycommand.log
1 2 * * * /path/to/your/command >/tmp/mycommand.log 2>&1

ดูบันทึก

Cron บันทึกการกระทำของตนผ่านทาง syslog ซึ่ง (ขึ้นอยู่กับการตั้งค่าของคุณ) มักจะไปหรือ/var/log/cron/var/log/syslog

หากจำเป็นคุณสามารถกรองคำสั่ง cron ด้วยเช่น

grep CRON /var/log/syslog 

ตอนนี้เราได้ผ่านพื้นฐานของ cron แล้วไฟล์เหล่านั้นอยู่ที่ไหนและวิธีการใช้งานพวกเรามาดูปัญหาทั่วไปกันบ้าง

ตรวจสอบ cron ที่กำลังทำงานอยู่

หาก cron ไม่ทำงานคำสั่งของคุณจะไม่ถูกกำหนด ...

ps -ef | grep cron | grep -v grep

คุณควรได้รับสิ่งที่ชอบ

root    1224   1  0 Nov16 ?    00:00:03 cron

หรือ

root    2018   1  0 Nov14 ?    00:00:06 crond

ถ้าไม่รีสตาร์ท

/sbin/service cron start

หรือ

/sbin/service crond start

อาจมีวิธีอื่น ใช้สิ่งที่ distro ของคุณมอบให้

cron รันคำสั่งของคุณในสภาพแวดล้อมที่ จำกัด

ตัวแปรสภาพแวดล้อมใดที่มีอยู่มีแนวโน้มว่าจะ จำกัด มาก โดยปกติแล้วคุณจะได้รับตัวแปรไม่กี่ที่กำหนดไว้เช่น$LOGNAME, และ$HOME$PATH

ของโปรดโดยเฉพาะคือจะมีการPATH จำกัด ปัญหาส่วนใหญ่ของ "สคริปต์ cron ของฉันไม่ทำงาน" เกิดจากเส้นทางที่ จำกัดนี้ หากคำสั่งของคุณอยู่ในตำแหน่งอื่นคุณสามารถแก้ปัญหานี้ได้สองวิธี:/bin:/usr/bin

  1. ระบุเส้นทางแบบเต็มไปยังคำสั่งของคุณ

    1 2 * * * /path/to/your/command
    
  2. ระบุ PATH ที่เหมาะสมในไฟล์ crontab

    PATH=/usr:/usr/bin:/path/to/something/else
    1 2 * * * command 
    

หากคำสั่งของคุณต้องการตัวแปรสภาพแวดล้อมอื่น ๆ คุณสามารถกำหนดได้ในไฟล์ crontab เช่นกัน

cron รันคำสั่งของคุณด้วย cwd == $ HOME

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

คำสั่งสุดท้ายใน crontab ของฉันไม่ทำงาน

โดยทั่วไป Cron ต้องการให้คำสั่งถูกยกเลิกด้วยบรรทัดใหม่ แก้ไข crontab ของคุณ ไปที่จุดสิ้นสุดของบรรทัดที่มีคำสั่งสุดท้ายและแทรกบรรทัดใหม่ (กด Enter)

ตรวจสอบรูปแบบ crontab

คุณไม่สามารถใช้ crontab ที่จัดรูปแบบผู้ใช้สำหรับ / etc / crontab หรือแฟรกเมนต์ใน /etc/cron.d และในทางกลับกัน ผู้ใช้ที่จัดรูปแบบ crontab จะไม่มีชื่อผู้ใช้ในตำแหน่งที่ 6 ของแถวในขณะที่ระบบที่จัดรูปแบบ crontab จะมีชื่อผู้ใช้และเรียกใช้คำสั่งในฐานะผู้ใช้นั้น

ฉันใส่ไฟล์ไว้ใน /etc/cron.{hourly,daily,weekly,monthly} และมันไม่ทำงาน

  • ตรวจสอบว่าชื่อไฟล์ไม่มีส่วนขยายให้ดูส่วนที่รัน
  • ตรวจสอบให้แน่ใจว่าไฟล์มีสิทธิ์ดำเนินการ
  • บอกระบบว่าจะใช้อะไรเมื่อเรียกใช้งานสคริปต์ของคุณ (เช่นวางไว้#!/bin/shด้านบน)

ข้อผิดพลาดที่เกี่ยวข้องกับวันที่ Cron

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

เปอร์เซ็นต์สัญญาณอีกครั้ง

ในการเน้นคำแนะนำเกี่ยวกับเครื่องหมายเปอร์เซ็นต์นี่คือตัวอย่างของ cron ที่ทำกับพวกเขา:

# cron entry
* * * * * cat >$HOME/cron.out%foo%bar%baz

จะสร้างไฟล์ ~ / cron.out ที่มี 3 บรรทัด

foo
bar
baz

นี่เป็นการรบกวนโดยเฉพาะอย่างยิ่งเมื่อใช้dateคำสั่ง ให้แน่ใจว่าได้หลบหนีสัญญาณร้อยละ

* * * * * /path/to/command --day "$(date "+\%Y\%m\%d")"

อาจต้องการพูดถึงในส่วน 'env ที่ถูก จำกัด ' ซึ่ง LD_LIBRARY_PATH อาจต้องมีไดเรกทอรีเพิ่มเติมที่ตั้งไว้ในกรณีที่งาน cron ของคุณล้มเหลวเนื่องจากไม่สามารถค้นหาไลบรารีที่แชร์ได้
DavidJ

โปรดทราบว่าคุณยังสามารถเขียนสิ่งนี้: 35 1,5-23 / 2 * * * do_something แทน 35,1,5,7,9, .. * * * นอกจากนี้crontab.guruนี้ยังแปลรายการที่คุณทำเพื่อ ภาษามนุษย์
Dennis Nolte

1
การส่งออกจับไม่ได้สำหรับฉันอาจเป็นเพราะเปลือก sh ผมคิดว่านี่เป็นแบบพกพาอื่น ๆ : ... /path/to/your/command >/tmp/mycommand.log 2>&1
Chus

สิ่งนี้ใช้ได้กับฉัน:sudo apt-get install postfix
jmunsch

งาน cron นั้นยังขึ้นอยู่กับไฟล์ว่าหนักแค่ไหน? เพราะฉันวิ่งสวัสดีโลกอย่างง่าย ๆ ด้วยงูใหญ่มันทำงานได้ดี แต่รหัสที่สองของฉันหนักไปหน่อยและโดยปกติแล้วจะทำงาน แต่ด้วย cron จะไม่ให้ผลลัพธ์ใด ๆ ลงในไฟล์
Devendra Bhat

22

Debian Linux และอนุพันธ์ของมัน (Ubuntu, Mint, ฯลฯ ) มีลักษณะบางอย่างที่อาจป้องกันไม่ให้งาน cron ของคุณทำงาน; โดยเฉพาะอย่างยิ่งไฟล์ใน/etc/cron.d, /etc/cron.{hourly,daily,weekly,monthly}ต้อง:

  • เป็นเจ้าของโดย root
  • สามารถเขียนได้โดย root เท่านั้น
  • ไม่สามารถเขียนได้โดยกลุ่มหรือผู้ใช้อื่น ๆ
  • มีชื่อโดยไม่มีจุดใด ๆ '.' หรืออักขระพิเศษอื่น ๆ ยกเว้น '-' และ '_'

คนสุดท้ายเจ็บผู้ใช้ที่ไม่สงสัยอย่างสม่ำเสมอ โดยเฉพาะอย่างยิ่งสคริปต์ใด ๆ ในหนึ่งในโฟลเดอร์เหล่านี้ชื่อwhatever.sh, mycron.py, testfile.plฯลฯ จะไม่ได้รับการดำเนินการที่เคย

จากประสบการณ์ของฉันประเด็นนี้เป็นเหตุผลที่พบบ่อยที่สุดสำหรับ cronjob ที่ไม่ดำเนินการกับ Debian และตราสารอนุพันธ์

ดูman cronรายละเอียดเพิ่มเติมหากจำเป็น


19

หาก cronjobs ของคุณหยุดทำงานตรวจสอบว่ารหัสผ่านของคุณยังไม่หมดอายุเนื่องจากเมื่อมีแล้วงาน cron ทั้งหมดจะหยุดทำงาน
จะมีข้อความ/var/log/messagesคล้ายกับข้อความด้านล่างซึ่งแสดงปัญหาเกี่ยวกับการตรวจสอบสิทธิ์ผู้ใช้:

(username) FAILED to authorize user with PAM (Authentication token is no longer valid; new one required)


2
เพิ่งได้รับเช่นกัน (ไฟล์ข้อความข้อผิดพลาด / var / log / syslog สำหรับฉัน) ในกรณีของฉันกล่อง DigitalOcean ที่ในเวลาสร้างพวกเขารีเซ็ตรหัสผ่านรูท (เป็นทางเลือก) เป็นอีกหนึ่งและเห็นได้ชัดว่าจนกว่าคุณจะไปที่นั่นและเปลี่ยนมันงาน cron ทั้งหมดไม่ทำงาน คนเกียจคร้าน แก้ไขเป็นเหมือนsudo -u root passwd
rogerdpack

12

ตารางที่ผิดปกติและผิดปกติ

Cron คือทุกสิ่งที่ถือว่าเป็นตัวกำหนดตารางเวลาพื้นฐานมากและไวยากรณ์ไม่อนุญาตให้ผู้ดูแลระบบกำหนดตารางเวลาที่ผิดปกติได้ง่ายขึ้นอีกเล็กน้อย

พิจารณางานต่อไปนี้ซึ่งมักจะอธิบายให้"ทำงานcommandทุก 5 นาที" :

*/5 * * * * /path/to/your/command

เมื่อเทียบกับ:

*/7 * * * * /path/to/your/command

ซึ่ง ไม่ได้เสมอทำงานcommandทุก 7 นาที

โปรดจำไว้ว่า/ตัวละครนั้นสามารถนำไปใช้เพื่อแนะนำขั้นตอน แต่ขั้นตอนนั้นไม่ได้ครอบคลุมกว่าตอนจบของซีรีย์เช่น*/7ซึ่งตรงกับทุกนาทีที่ 7 จากนาที0-59 เช่น 0,7,14,21,28,35,42,49 56 แต่ระหว่างหนึ่งชั่วโมงถัดไปจะมีเพียง 4 นาทีระหว่างสำหรับกระบวนการหลังจาก 00:56ชุดใหม่เริ่มต้นที่ 01:00, 01:07ฯลฯ (และสำหรับกระบวนการจะไม่ทำงานบน01:03, 01:10, 01:17ฯลฯ )


จะทำอย่างไรแทน

สร้างแบทช์หลายชุด

แทนที่จะเป็นงาน cron เดียวให้สร้างหลายชุดที่รวมผลลัพธ์ไว้ในตารางที่ต้องการ

ตัวอย่างเช่นการเรียกใช้แบทช์ทุก ๆ 40 นาที (00:00, 00:40, 01:20, 02:00 เป็นต้น) สร้างสองแบทช์หนึ่งแบทช์ที่รันสองครั้งในชั่วโมงที่สองและที่สองที่รันเฉพาะเวลาคี่:

# The following lines create a batch that runs every 40 minutes i.e.

# runs on   0:00, 0:40,        02:00, 02:40         04:00 etc to 22:40
0,40 */2 * * * /path/to/your/command

# runs on               01:20,               03:20,       etc to 23:20
20 1/2 * * * /path/to/your/command

# Combined: 0:00, 0:40, 01:20, 02:00, 02:40, 03:20, 04:00 etc.

เรียกใช้ชุดงานของคุณน้อยลง

แทนที่จะใช้งานแบทช์ของคุณทุก ๆ 7 นาทีซึ่งเป็นช่วงเวลาที่ยากที่จะแยกย่อยเป็นหลาย ๆ แบทช์เพียงรันทุก ๆ 10 นาทีแทน

เริ่มแบตช์ของคุณบ่อยขึ้น (แต่ป้องกันไม่ให้แบตช์หลายชุดทำงานพร้อมกัน)

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

ให้คิดต่างกันและสร้าง cronjob ที่จะล้มเหลวอย่างสวยงามเมื่อการรันก่อนหน้ายังไม่เสร็จ แต่จะทำงานเป็นอย่างอื่น ดูคำถาม & คำตอบนี้ :

* * * * * /usr/bin/flock -n /tmp/fcj.lockfile /usr/local/bin/frequent_cron_job 

ที่จะเริ่มต้นการทำงานใหม่เกือบจะทันทีเมื่อการรัน / usr / local / bin / Frequ_cron_job ก่อนหน้านี้เสร็จสิ้น

เริ่มแบตช์ของคุณบ่อยขึ้น (แต่ออกอย่างสง่างามเมื่อเงื่อนไขไม่ถูกต้อง)

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

ในทุบตีseven-minute-jobแล้วจะมีลักษณะเหมือน:

#!/bin/bash
# seven-minute-job
# This batch will only run when 420 seconds (7 min) have passed
# since the file /tmp/lastrun was either created or updated

if [ ! -f /tmp/lastrun ] ; then
    touch /tmp/lastrun
fi

if [ $(( $(date +%s) - $(date -r /tmp/lastrun +%s) )) -lt 420 ] ; then
     # The minimum interval of 7 minutes between successive batches hasn't passed yet.
    exit 0
fi

####  Start running your actual batch job below

/path/to/your/command

#### actual batch job is done, now update the time stamp
date > /tmp/lastrun
#EOF

ซึ่งคุณสามารถ (พยายาม) อย่างปลอดภัยเพื่อให้ทำงานทุกนาที:

* * * * * /path/to/your/seven-minute-job

ที่แตกต่างกัน แต่ที่คล้ายกันปัญหาจะเพื่อกำหนดตารางการชุดที่จะทำงานในวันจันทร์แรกของทุกเดือน (หรือสองวันพุธ) ฯลฯ เพียงแค่กำหนดเวลาชุดที่จะทำงานทุกวันจันทร์และออกเมื่อวันที่ค่าระหว่าง 1 เซนต์หรือ 7 วันและ วันในสัปดาห์ไม่ใช่วันจันทร์

#!/bin/bash
# first-monday-of-the-month-housekeeping-job

# exit if today is not a Monday (and prevent locale issues by using the day number) 
if [ $(date +%u) != 1 ] ; then
  exit 0
fi

# exit if today is not the first Monday
if [ $(date +%d) -gt 7 ] ; then
  exit 0
fi

####  Start running your actual batch job below

/path/to/your/command

#EOF

ซึ่งคุณสามารถทำได้อย่างปลอดภัย (พยายาม) ให้ทำงานทุกวันจันทร์:

0 0 * * 1 /path/to/your/first-monday-of-the-month-housekeeping-job

อย่าใช้ cron

หากความต้องการของคุณซับซ้อนคุณอาจพิจารณาใช้ผลิตภัณฑ์ขั้นสูงเพิ่มเติมที่ออกแบบมาเพื่อเรียกใช้ตารางเวลาที่ซับซ้อน (กระจายผ่านเซิร์ฟเวอร์หลายเครื่อง) และที่สนับสนุนทริกเกอร์การพึ่งพางานการจัดการข้อผิดพลาดลองใหม่และการตรวจสอบความพยายามอีกครั้ง " การจัดตารางงานและ / หรือ" การทำงานอัตโนมัติของภาระงาน "


8

PHP เฉพาะ

หากคุณมีงาน cron เช่น:

php /bla/bla/something.php >> /var/logs/somelog-for-stdout.log

และในกรณีที่มีข้อผิดพลาดคาดว่าพวกเขาจะถูกส่งถึงคุณ แต่พวกเขาไม่ได้ - ตรวจสอบนี้

PHP โดยค่าเริ่มต้นไม่ได้ส่งข้อผิดพลาดไปยัง STDOUT @see https://bugs.php.net/bug.php?id=22839

ในการแก้ไขปัญหานี้ให้เพิ่ม phi.ini ของ cli`s หรือในบรรทัดของคุณ (หรือใน bash wrapper สำหรับ PHP ของคุณ) สิ่งเหล่านี้:

  • - กำหนด display_startup_errors = 1
  • - กำหนด display_errors = 'stderr'

การตั้งค่าที่ 1 จะช่วยให้คุณมีคนเสียชีวิตเช่น 'Memory oops' และ 2nd - เพื่อเปลี่ยนเส้นทางพวกเขาทั้งหมดไปยัง STDERR หลังจากที่คุณสามารถนอนหลับได้ดีแล้วทุกคนจะถูกส่งไปยังอีเมลล์รูทของคุณแทนที่จะเข้าสู่ระบบ


2
รายงานข้อผิดพลาดนั้นถูกปิดลงในปี 2550 โดยมีสถานะของแพตช์ที่เพิ่มเข้ากับสาขา PHP 5.2+ คุณแน่ใจหรือไม่ว่านี่เป็นสิ่งจำเป็น ฉันเพิ่งลองใช้ PHP 5.4 และดูเหมือนว่าจะทำงานได้ดี (มันยังจำเป็นสำหรับ PHP 4 แม้ว่า)
Xeoncross

@Xeoncross ดูวันที่คำตอบ :)
gaRex

1
ใช่นั่นคือสิ่งที่ฉันสับสนตั้งแต่คุณตอบในปี 2013 และตั๋วกลับมาในปี 07
Xeoncross

0

การเพิ่มคำตอบจากที่นี่เพื่อความครบถ้วนและเพิ่มแหล่งข้อมูลที่เป็นประโยชน์อื่น:

cronผู้ใช้มีความแตกต่าง$PATHกว่าที่คุณทำ:

ปัญหาที่ผู้ใช้ทำกับcrontabรายการบ่อยครั้งคือพวกเขาลืมว่าcronทำงานต่างenvironmentจากผู้ใช้ที่เข้าสู่ระบบ ตัวอย่างเช่นผู้ใช้สร้างโปรแกรมหรือสคริปต์ใน$HOMEไดเรกทอรีของเขาและป้อนคำสั่งต่อไปนี้เพื่อเรียกใช้:

$ ./certbot ... 

คำสั่งทำงานอย่างสมบูรณ์แบบจากบรรทัดคำสั่งของเขา จากนั้นผู้ใช้เพิ่มคำสั่งนั้นลงไปcrontabแต่พบว่าสิ่งนี้ไม่ทำงาน:

*/10 * * * * ./certbot ....

สาเหตุของความล้มเหลวในกรณีนี้./คือเป็นตำแหน่งที่แตกต่างกันสำหรับcronผู้ใช้มากกว่าสำหรับผู้ใช้ที่เข้าสู่ระบบ นั่นคือความenvironmentแตกต่าง! PATH เป็นส่วนหนึ่งของenvironmentและมักแตกต่างกันสำหรับcronผู้ใช้ แทรกซ้อนปัญหานี้เป็นที่environmentสำหรับการcronไม่ได้เป็นเหมือนกันสำหรับทุก* ระวังการกระจายและมีหลายรุ่นcron

ทางออกที่ง่ายสำหรับปัญหาเฉพาะนี้คือการให้cronข้อมูลจำเพาะของพา ธ ที่สมบูรณ์แก่ผู้ใช้ในcrontabรายการ:

0 22 * * * /path/to/certbot .....

อะไรคือสิ่งที่cronผู้ใช้environment?

ในบางกรณีเราอาจจำเป็นต้องทราบenvironmentข้อกำหนดที่สมบูรณ์สำหรับcronระบบของเรา (หรือเราอาจจะอยากรู้อยากเห็น) คืออะไรenvironmentสำหรับcronผู้ใช้และวิธีการที่แตกต่างจากเรา? นอกจากนี้เราอาจจำเป็นต้องทราบผู้ใช้รายenvironmentอื่นcron- rootตัวอย่างเช่น ... rootผู้ใช้กำลังenvironmentใช้cronอะไร วิธีหนึ่งในการเรียนรู้สิ่งนี้คือขอcronให้บอกเรา:

  1. สร้างเชลล์สคริปต์ในโฮมไดเร็กตอรี่ของคุณ ( ~/) ดังต่อไปนี้ (หรือด้วยตัวแก้ไขที่คุณเลือก):
$ nano ~/envtst.sh
  1. ป้อนสิ่งต่อไปนี้ในโปรแกรมแก้ไขหลังจากปรับสำหรับระบบ / ผู้ใช้ของคุณ:
#!/bin/sh 
/bin/echo "env report follows for user "$USER >> /home/you/envtst.sh.out 
/usr/bin/env >> /home/you/envtst.sh.out 
/bin/echo "env report for user "$USER" concluded" >> /home/you/envtst.sh.out
/bin/echo " " >> /home/you/envtst.sh.out
  1. บันทึกไฟล์ออกจากตัวแก้ไขและตั้งค่าอนุญาตสำหรับไฟล์เป็นไฟล์เรียกทำงาน
$ chmod a+rx ~/envtst.sh
  1. /home/you/envtst.sh.outเรียกใช้สคริปต์ที่คุณเพิ่งสร้างและตรวจสอบการส่งออกใน ผลลัพธ์นี้จะแสดงสภาพแวดล้อมปัจจุบันของคุณในขณะที่$USERคุณเข้าสู่ระบบในฐานะ:
$ ./envtst.sh $$ cat /home/you/envtst.sh.out
  1. เปิดของคุณcrontabเพื่อแก้ไข:
$ crontab -e -u root
  1. ป้อนบรรทัดต่อไปนี้ที่ด้านล่างของคุณcrontab:
* * * * *  /home/you/envtst.sh >> /home/you/envtst.sh.err 2>&1

คำตอบ:ไฟล์เอาต์พุต/home/you/envtst.sh.outจะมีรายการของenvironmentสำหรับ "ผู้ใช้ root cron" เมื่อคุณทราบแล้วให้ปรับcrontabรายการของคุณให้สอดคล้อง

ฉันไม่สามารถระบุตารางเวลาที่ฉันต้องการในcrontabรายการของฉัน:

มีการกำหนดตารางเวลาสำหรับcrontabหลักสูตรman crontabและคุณควรอ่านสิ่งนี้ อย่างไรก็ตามการอ่านman crontabและทำความเข้าใจกับตารางเป็นสองสิ่งที่แตกต่างกัน และการทดลองและข้อผิดพลาดตามข้อกำหนดกำหนดการอาจกลายเป็นเรื่องน่าเบื่อมาก โชคดีที่มีทรัพยากรที่สามารถช่วยได้: กูรู crontab . ป้อนข้อมูลกำหนดตารางเวลาของคุณแล้วมันจะอธิบายตารางเรียนเป็นภาษาอังกฤษแบบธรรมดา

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

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