เกิดอะไรขึ้นกับงาน cron ทั้งสองนี้


13

ฉันมีงาน cron ดังต่อไปนี้ที่กำหนดไว้

55  8   *   *   3   /usr/bin/php /home/mark/dev/processes/customClient/events.php > /home/mark/dev/processes/customClient/events-`date +%Y-%m-%d --date='last Wednesday'`-`date +%Y-%m-%d`.csv
0   9   *   *   3   /usr/bin/echo 'The csv for last week, trying my hand at automatiging this' | /usr/bin/mutt <emailaddress> -s 'Events from `date +%Y-%m-%d --date='last Wednesday'`-`date +%Y-%m-%d`' -a '/home/mark/dev/processes/customClient/events-`date +%Y-%m-%d --date='last Wednesday'`-`date +%Y-%m-%d`.csv'

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


FYI ฉันเพิ่งทดสอบ cron ใหม่และได้รับข้อผิดพลาดดังต่อไปนี้ /bin/sh: 1: Syntax error: EOF in backquote substitution สำหรับงาน cron แรก /bin/sh: 1: Syntax error: Unterminated quoted string สำหรับงาน cron ที่สอง
Mark D

2
Backticks ถูกคัดค้านด้วยเหตุผลนี้; เปลี่ยนไป$(...)จะช่วยให้คุณจัดการกับปัญหา quoting ...
jasonwryan

1
แน่นอนคุณต้องการตรวจสอบคำถามของฉัน มีคำตอบจาก Stephane Chazelas ที่อธิบายวิธีที่คุณสามารถสร้างเชลล์แบบโต้ตอบที่เหมือนกับสภาพแวดล้อมที่งาน cron ของคุณจะเห็น ถ้าคุณทำตามขั้นตอนเล็ก ๆ ของเขาคุณจะได้รับพรอมต์และคุณสามารถทดสอบขั้นตอนการ cronjob ของคุณทีละขั้นตอนและดูว่ามันล้มเหลวที่ไหน unix.stackexchange.com/a/56503/16841 แน่นอนว่าไม่ใช่คำถามที่ตรงกัน 100% สำหรับคำถามของคุณ แต่สามารถช่วยคุณแก้ไขปัญหา crontab ได้
jippie

คำตอบ:


14

ฉันขอแนะนำให้ใส่งาน cron ที่ไม่สำคัญลงในไฟล์สคริปต์เชลล์ของตัวเองด้วยเหตุผลหลายประการ:

  • ง่ายต่อการตรวจแก้จุดบกพร่อง: คุณสามารถเรียกใช้สคริปต์แทนที่จะคัดลอกวางเป็นบรรทัดยาวและด้วยเส้น Shebang ที่ถูกต้องมันจะทำงานได้ดีกว่าการคาดเดามากกว่าถ้าคุณมีคำสั่งเดียวกันใน crontab โดยตรง
  • ง่ายต่อการอ่าน: ไม่จำเป็นต้องทำให้เป็นหนึ่งใน 200 ตัวอักษรคุณสามารถจัดรูปแบบได้อย่างดีดังนั้นจึงง่ายต่อการอ่านและเข้าใจสำหรับทุกคน
  • เพิ่มสคริปต์ในการควบคุมเวอร์ชัน

8
และการใส่%ตัวละครที่มีปัญหาลงไปในสคริปต์จะช่วยป้องกันไม่ให้cronพวกเขาเปลี่ยนเป็นบรรทัดใหม่ซึ่งเป็นปัญหาที่แท้จริงของคุณ
เอียนดี. อัลเลน

ฉันไม่เห็นด้วย. คุณมักจะลืมว่าสคริปต์ทำอะไร ฉันกำลังพูดจากประสบการณ์
Sridhar Sarnobat

30

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

  • Cron จัดให้มีสภาพแวดล้อมที่ จำกัด เช่น$PATHตัวแปรขั้นต่ำและตัวแปรอื่น ๆ ที่ขาดหายไป
  • Cron จะเรียกใช้/bin/shตามค่าเริ่มต้นในขณะที่คุณอาจใช้เชลล์ตัวอื่นแบบโต้ตอบ
  • Cron ปฏิบัติต่อ%ตัวละครเป็นพิเศษ (มันจะกลายเป็นบรรทัดใหม่ในคำสั่ง)
  • Cron ไม่ได้จัดเตรียมเทอร์มินัลหรือสภาพแวดล้อมแบบกราฟิก

คุณต้องนำหน้า%อักขระทั้งหมดด้วย a \ในไฟล์ crontab ซึ่งจะบอก cron ให้ใส่เปอร์เซ็นต์ในคำสั่ง จำไว้ว่าเมื่อคุณใช้dateคำสั่งในงาน cron

55  8   *   *   3   /usr/bin/php /home/mark/dev/processes/customClient/events.php > "/home/mark/dev/processes/customClient/events-$(date +\%Y-\%m-\%d --date='last Wednesday')-$(date +\%Y-\%m-\%d).csv"
0   9   *   *   3   /usr/bin/echo 'The csv for last week, trying my hand at automatiging this' | /usr/bin/mutt <emailaddress> -s "Events from $(date +\%Y-\%m-\%d --date='last Wednesday')-$(date +\%Y-\%m-\%d)" -a "/home/mark/dev/processes/customClient/events-$(date +\%Y-\%m-\%d --date='last Wednesday')-$(date +\%Y-\%m-\%d).csv"

ฉันยังแก้ไขปัญหาการอ้างอิง:

  • นี่ไม่ได้ทำให้คุณมีปัญหานอกเหนือจากความชัดเจน แต่คุณไม่ควรใช้ backticks เพื่อทดแทนคำสั่ง ใช้$(…)แทน: กฎการแยกวิเคราะห์นั้นง่ายกว่า
  • "$somevariable"มักจะใช้คำพูดสองรอบตัวแปรและคำสั่งแทน: "$(somecommand)", ที่นี่การขาดเครื่องหมายคำพูดไม่เป็นอันตรายเพราะdateคำสั่งไม่เคยส่งคืนอักขระพิเศษใด ๆ สำหรับรูปแบบที่คุณใช้ แต่คุณต้องจำอย่างระมัดระวังว่าอักขระใดเป็นพิเศษและตรวจสอบสิ่งนี้ทุกครั้งที่คุณออกจากการแทนที่โดยไม่มีการอ้างอิง ทำให้มันง่ายใช้เครื่องหมายคำพูดคู่เสมอยกเว้นว่าคุณต้องการให้การแบ่งฟิลด์และการสร้างชื่อไฟล์เกิดขึ้นกับผลลัพธ์
  • คุณมีอัญประกาศเดี่ยวที่ป้องกันการขยายรอบการแทนที่คำสั่งบางอย่าง ใช้เครื่องหมายคำพูดคู่แทน

0

ดูเหมือนว่าคุณจะซ้อน'ในmuttคำสั่ง:

'กิจกรรมจากdate +%Y-%m-%d --date='last Wednesday'- date +%Y-%m-%d'

ลองใช้"แทนด้านใน'เพื่อให้คำสั่งอ่าน

'กิจกรรมจากdate +%Y-%m-%d --date="last Wednesday"- date +%Y-%m-%d'


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