ทำไมสคริปต์ crontab ไม่ทำงาน


525

บ่อยครั้งที่crontabสคริปต์จะไม่ถูกดำเนินการตามกำหนดเวลาหรือตามที่คาดไว้ มีเหตุผลมากมายที่:

  1. สัญกรณ์ crontab ผิด
  2. ปัญหาการอนุญาต
  3. ตัวแปรสภาพแวดล้อม

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

โปรดระบุเหตุผลหนึ่งข้อต่อคำตอบ - รายละเอียดเกี่ยวกับสาเหตุที่ไม่ได้ดำเนินการ - และแก้ไขด้วยเหตุผลหนึ่งข้อ

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


12
คุณต้องปิดcrontab -ecron เพื่อรับผลกระทบ เช่นการใช้ vim ฉันแก้ไขไฟล์และใช้:wเพื่อเขียน แต่งานจะไม่ถูกเพิ่มใน cron จนกว่าฉันจะออกจาก ดังนั้นฉันจะไม่เห็นงานจนกระทั่งหลังจากฉัน:qด้วย
DutGRIFF

ฉันคิดว่าวิธีที่ดีที่สุดในการดีบัก cron คือการตรวจสอบ syslog และค้นหาปัญหา
Suneel Kumar

ในกรณีของฉัน - อีเมลกำลังจะไปยังโฟลเดอร์สแปมของฉันดังนั้น ..... ตรวจสอบก่อนที่คุณจะใช้เวลาหลายชั่วโมงในการดีบัก: D
almaruf

ไฟฟ้าดับ
Josef Klimuk

คำตอบ:


501

สภาพแวดล้อมที่แตกต่างกัน

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

* * * * * env> /tmp/env.output

รอ/tmp/env.outputการสร้างจากนั้นลบงานอีกครั้ง ตอนนี้เปรียบเทียบเนื้อหาของ/tmp/env.outputกับเอาต์พุตของการenvรันในเทอร์มินัลปกติของคุณ

"gotcha" ทั่วไปที่นี่คือPATHตัวแปรสภาพแวดล้อมที่แตกต่างกัน บางทีสคริปต์ cron ของคุณใช้คำสั่งsomecommandที่พบใน/opt/someApp/binที่ที่คุณเพิ่มลงPATHใน/etc/environment? cron ละเว้นPATHจากไฟล์นั้นดังนั้นการsomecommandรันจากสคริปต์ของคุณจะล้มเหลวเมื่อรันด้วย cron แต่ทำงานเมื่อรันในเทอร์มินัล มันเป็นที่น่าสังเกตว่าตัวแปรจาก/etc/environmentจะถูกส่งผ่านไปยังงาน cron เพียงแค่ไม่ได้เป็นตัวแปร cron PATHเฉพาะชุดตัวเองเช่น

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

#!/bin/bash
PATH=/opt/someApp/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

# rest of script follows

บางคนชอบที่จะใช้พา ธ สัมบูรณ์กับคำสั่งทั้งหมดแทน ฉันขอแนะนำว่า พิจารณาสิ่งที่เกิดขึ้นหากคุณต้องการเรียกใช้สคริปต์ของคุณในระบบอื่นและในระบบนั้นคำสั่งจะทำงาน/opt/someAppv2.2/binแทน คุณจะต้องผ่านสคริปต์ทั้งหมดแทนที่/opt/someApp/binด้วย/opt/someAppv2.2/binแทนที่จะแก้ไขเพียงเล็กน้อยในบรรทัดแรกของสคริปต์

คุณยังสามารถตั้งค่าตัวแปร PATH ในไฟล์ crontab ซึ่งจะใช้กับงาน cron ทั้งหมด เช่น

PATH=/opt/someApp/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

15 1 * * * backupscript --incremental /home /root

5
ฉันคิดว่าฉันตกหลุมรักสิ่งนี้และขึ้นบรรทัดใหม่ในตอนท้าย ...
WernerCD

6
+1 สำหรับenvฉันลืมไปแล้วเกี่ยวกับคำสั่งนั้นและคิดว่า PATH ทำงานได้ดี จริง ๆ แล้วมันแตกต่างเล็กน้อยในกรณีของฉัน
Izkata

8
@pbr หากไดเรกทอรีดังกล่าวเหลือให้ผู้อื่นเขียนได้ระบบจะถูกบุกรุกไปแล้ว
geirha

6
@pbr ระบบดูแลระบบสามารถลบระบบไฟล์รูทได้โดยไม่เจตนา คุณไม่สามารถป้องกันผู้ดูแลระบบที่ทำผิดพลาดได้ หากคุณติดตั้งล่ามเวอร์ชันใหม่กว่าซึ่งไม่รองรับการทำงานย้อนหลัง วิธีที่มีเหตุผลในการจัดการนั่นคือการติดตั้งมันเป็นคำสั่งที่แตกต่างกัน เช่นคุณมี python เวอร์ชัน 2.x และติดตั้ง python 3 คุณติดตั้งเป็น python3 ไม่ใช่ python และสำหรับ / opt / someApp / bin ทำไมบนโลกนี้ถึงไม่มีสิทธิ์ใช้งาน / ความเป็นเจ้าของ? ผู้ดูแลระบบที่มีสติใด ๆ จะช่วยให้มั่นใจได้ถึงสิทธิ์ / ความเป็นเจ้าของในไฟล์ระบบ
geirha

2
@pbr ดูเหมือนว่าเราจะไปได้ตลอดไปใช่ ฉันยังคงล้มเหลวที่จะดูว่าทำไมจึงเป็นความคิดที่ดีที่จะใช้ PATH แม้ว่า หากคุณต้องการพูดคุยเรื่องนี้เพิ่มเติมในสื่อที่เหมาะสำหรับการอภิปรายคุณจะพบฉันใน #ubuntu และ #bash ท่ามกลางช่องอื่น ๆ บน irc.freenode.net
geirha

336

gotcha อันดับต้น ๆ ของฉัน: หากคุณลืมเพิ่มบรรทัดใหม่ที่ท้ายcrontabไฟล์ กล่าวอีกนัยหนึ่งไฟล์ crontab ควรลงท้ายด้วยบรรทัดว่าง

ด้านล่างเป็นส่วนที่เกี่ยวข้องในหน้าคนสำหรับปัญหานี้ ( man crontabจากนั้นข้ามไปยังจุดสิ้นสุด):

   Although cron requires that each entry in a crontab end  in  a  newline
   character,  neither the crontab command nor the cron daemon will detect
   this error. Instead, the crontab will appear to load normally. However,
   the  command  will  never  run.  The best choice is to ensure that your
   crontab has a blank line at the end.

   4th Berkeley Distribution      29 December 1993               CRONTAB(1)

91
นี่มันช่างเป็น showstopper ทำไมมันถึงไม่ได้รับการแก้ไขใน cron เป็นเวลาหลายปี?
Capi Etheriel

2
ดูเหมือนว่าจะได้รับการแก้ไขใน Vixie cron: man crontabบน Ubuntu 10.10 กล่าวว่า "cron ต้องการให้แต่ละรายการใน crontab ลงท้ายด้วยอักขระขึ้นบรรทัดใหม่หากรายการสุดท้ายใน crontab หายไปขึ้นบรรทัดใหม่ cron จะพิจารณา crontab (อย่างน้อยบางส่วน) และปฏิเสธที่จะติดตั้ง " (และวันที่สิ้นสุดคือ 19 เมษายน 2010)
Marius Gedminas

19
@barraponto นี่เป็นข้อผิดพลาดในโปรแกรมแก้ไขข้อความใหม่ อักขระ "ขึ้นบรรทัดใหม่" ควรเป็นอักขระการยกเลิกบรรทัดดังนั้นบรรทัดสุดท้ายในไฟล์ข้อความควรจะลงท้ายด้วยอักขระขึ้นบรรทัดใหม่ที่ไม่แสดงในตัวแก้ไข Vi และกลุ่มใช้ตัวอักษรอย่างถูกต้องและ cron ถูกสร้างขึ้นก่อนที่บรรณาธิการใหม่จะเริ่มพฤติกรรมแปลก ๆ ของพวกเขา ... ดังนั้นการเล่นมันจะบันทึกและรวมถึงบรรทัดว่าง
Izkata

6
หากคุณแก้ไข crontab โดยใช้crontab -eมันจะตรวจสอบไวยากรณ์ของไฟล์ก่อนอนุญาตให้บันทึกรวมถึงการตรวจสอบการขึ้นบรรทัดใหม่
Tom Harrison Jr

2
@ Chan-HoSuh อ้างอิงจาก man page "cron ต้องการให้แต่ละรายการใน crontab ลงท้ายด้วยอักขระขึ้นบรรทัดใหม่หากรายการสุดท้ายใน crontab หายไปขึ้นบรรทัดใหม่ cron จะพิจารณา crontab (อย่างน้อยบางส่วน) และจะปฏิเสธ ติดตั้ง " พฤติกรรมนี้จะถูกเรียกใช้เมื่อแก้ไขจากนั้นบันทึก crontab โดยใช้-eตัวเลือกและไม่ขึ้นอยู่กับโปรแกรมแก้ไข
ทอมแฮร์ริสันจูเนียร์

139

Cron daemon ไม่ทำงาน ฉันเมาแล้วเมื่อหลายเดือนก่อน

ประเภท:

pgrep cron 

หากคุณไม่เห็นหมายเลขใด cron จะไม่ทำงาน sudo /etc/init.d/cron startสามารถใช้เพื่อเริ่ม cron

แก้ไข: แทนที่จะเรียกใช้สคริปต์เริ่มต้นผ่าน /etc/init.d ให้ใช้ยูทิลิตีบริการเช่น

sudo service cron start

แก้ไข: นอกจากนี้คุณยังสามารถใช้ systemctl ใน Linux ที่ทันสมัยเช่น

sudo systemctl start cron

47
ขอบคุณที่แสดง pgrep ให้ฉัน ฉันทำ ps -ef | grep foo
ripper234

4
คุณสามารถใช้pidof cronซึ่งจะละเว้นผลลัพธ์สำหรับแอปพลิเคชันอื่น ๆ ที่มีคำว่า 'cron' เช่น crontab
Pithikos

แปลกสิ่งเหล่านี้ทำให้ฉันไม่มีอะไรจะแสดงให้เห็นว่า cron กำลังทำงานอยู่ แต่ถ้าฉันวิ่งไปsudo service cron startฉันจะได้start: Job is already running: cron
คอลลีน

1
service crond startถ้า centos / RHEL
Srihari Karanth

91

สคริปต์ชื่อไฟล์ในcron.d/, cron.daily/, cron.hourly/ฯลฯ ไม่ควรมีจุด ( .) มิฉะนั้นทำงานส่วนจะข้ามพวกเขา

ดู run-parts (8):

   If neither the --lsbsysinit option nor the --regex option is given then
   the names must consist entirely of upper and lower case  letters,  dig‐
   its, underscores, and hyphens.

   If  the  --lsbsysinit  option  is given, then the names must not end in
   .dpkg-old  or .dpkg-dist or .dpkg-new or .dpkg-tmp, and must belong  to
   one  or more of the following namespaces: the LANANA-assigned namespace
   (^[a-z0-9]+$);   the   LSB   hierarchical   and   reserved   namespaces
   (^_?([a-z0-9_.]+-)+[a-z0-9]+$);  and  the  Debian cron script namespace
   (^[a-zA-Z0-9_-]+$).

ดังนั้นถ้าคุณมีสคริปต์ cron backup.sh, analyze-logs.plในcron.daily/ไดเรกทอรีคุณควรที่ดีที่สุดเพื่อลบชื่อนามสกุล


10
มันเป็นคุณสมบัติที่ไม่ได้เป็นข้อผิดพลาด - มันเก็บสิ่งต่าง ๆ เช่น myscript.backup หรือ myscript.original หรือ myscript.rpm- ใหม่จากการทำงานอยู่ด้านข้าง myscript
pbr

@pbr: เข้าท่า อย่างน้อยก็มีประโยชน์สำหรับการดีบั๊กถ้าrun-parts --test(หรือตัวเลือกอื่น ๆ ในจินตนาการเช่น--debugจะเอาท์พุทไฟล์ที่มันข้ามรวมถึงเหตุผล
Rabarberski

8
หากนี่คือคุณสมบัติมันไม่ใช่สิ่งที่ดี :( ผู้คนจำนวนมากใช้จุดในชื่อไฟล์ (backup.sh เป็นชื่อสามัญที่สุด) หากคุณต้องการสคริปต์เพื่อหยุดการดำเนินการวิธีตรรกะส่วนใหญ่จะเป็น ลบออกจากไดเรกทอรี "cron.d"
MatuDuke

7
นี่เป็นคุณสมบัติที่ไม่ดีที่มีข้อบกพร่องอย่างมีประสิทธิภาพ มันเป็นเรื่องธรรมดาที่ต้องมีจุดสิ้นสุดเฉพาะ (เช่น ".list" หรือ ".cron" หรือบางอย่าง) หากผู้คนต้องการให้แน่ใจว่าสิ่งต่าง ๆ จะได้รับการดำเนินการเมื่อตั้งใจ การเลือกจุดโดยพลการเป็นตัวคั่นที่เป็นไปได้สำหรับ ".bak" หรือ ".temp" หรืออะไรก็ตามไม่สามารถคาดเดาได้อย่างสมบูรณ์ยกเว้นในลักษณะที่ว่ามันจะสร้างความสับสนให้กับผู้คน ตอนจบที่ถูกกฎหมายเช่น ".sh" และ ".pl" มีการใช้กันอย่างแพร่หลายมานานหลายทศวรรษ อย่างไรก็ตามผู้คนจำนวนมากใช้ "_bak" หรือ "_temp" หรือ "-bak" แทนที่จะเป็นจุด นี่คือตัวเลือกการออกแบบที่น่ากลัว มันเป็นข้อบกพร่องในการออกแบบที่ดีที่สุด
Teekin

68

ในสภาพแวดล้อมหลาย cron รันคำสั่งที่ใช้ในขณะที่หลายคนคิดจะใช้shbash

คำแนะนำในการทดสอบหรือแก้ไขปัญหานี้สำหรับคำสั่งที่ล้มเหลว:

  • ลองรันคำสั่งshเพื่อดูว่าทำงานได้หรือไม่:

    sh -c "mycommand"
    
  • ล้อมคำสั่งในเชลล์ย่อยของ bash เพื่อให้แน่ใจว่าคำสั่งนั้นรันใน bash:

    bash -c "mybashcommand"
    
  • บอก cron ให้รันคำสั่งทั้งหมดใน bash โดยการตั้งค่าเชลล์ที่ด้านบนของ crontab ของคุณ:

    SHELL=/bin/bash
    
  • หากคำสั่งเป็นสคริปต์ตรวจสอบให้แน่ใจว่าสคริปต์ประกอบด้วย shebang:

    #!/bin/bash
    

ข้อเสนอแนะทุบตีจะเป็นประโยชน์มากแก้ไขปัญหากับ cron ของฉัน
Maxim Galushka

นี่เพิ่งทำให้ฉันเล่นซอ / แก้ปัญหาได้ 1 ชั่วโมง แม้งงมากขึ้นถ้าคุณไม่ได้ตระหนักถึงปัญหานี้เป็นสคริปต์ที่จะทำงานด้วยตนเองได้ดีถ้าคุณเปลือกทั่วไปแต่ไม่ได้มีbash cronขอบคุณ!
Hendy

นานมาแล้วฉันพบสิ่งที่เกี่ยวข้อง: คำสั่งsourceอยู่ในทุบตี แต่ไม่ใช่ sh ใน cron / ดวลจุดโทษให้ใช้ระยะเวลา: มากกว่า. envfile source envfile
kungphu

@Clockwork sh "mycommand"บอกshให้รันmycommand เป็นไฟล์สคริปต์ คุณหมายถึงsh -c "mycommand"อะไร คำตอบนี้ดูเหมือนจะเกี่ยวกับการทำให้คำสั่งรันเป็น bash โดยเฉพาะดังนั้นคุณเพิ่มคำสั่งไว้shที่นี่ทำไม?
Olorin

@ Olorin จากความเข้าใจของฉันวัตถุประสงค์ของจุดแรกคือการลองและเรียกใช้ด้วย sh เพื่อดูว่าปัญหานั้นมาจากข้อเท็จจริงที่ cron ใช้มันด้วย sh แทนการทุบตี จากนั้นอีกครั้งฉันมีความรู้เล็กน้อยเกี่ยวกับเรื่องนี้ดังนั้นฉันอาจผิด
ลาน

39

ฉันมีปัญหาบางอย่างกับเขตเวลา Cron กำลังทำงานกับเขตเวลาการติดตั้งใหม่ ทางออกคือการรีสตาร์ท cron:

sudo service cron restart

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

โอ้เพื่อประโยชน์ของพระเจ้าฆ่าเวลานี้ พยายามบริการเริ่มต้นหลังจากที่* * * * * touch /tmp/cronworksไม่ได้ทำอะไรยังมีRELOADที่ cronlog
НЛО

36

พา ธ สัมบูรณ์ควรใช้สำหรับสคริปต์:

ตัวอย่างเช่น/bin/grepควรใช้แทนgrep:

# m h  dom mon dow   command
0 0 *  *  *  /bin/grep ERROR /home/adam/run.log &> /tmp/errors

แทน:

# m h  dom mon dow   command
0 0 *  *  *  grep ERROR /home/adam/run.log &> /tmp/errors

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


3
ดูคำตอบของ geirha คุณสามารถ (ต้อง) กำหนด PATH ของ cron
Capi Etheriel

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

1
ใช่นี่คือมันสำหรับฉันนอก cron ฉันสามารถเรียกใช้คำสั่งโดยตรงภายใน cron มันต้องการ/usr/bin/whateverเส้นทางแบบเต็ม
Anentropic

32

หากคำสั่ง crontab ของคุณมี%สัญลักษณ์อยู่ cron จะพยายามตีความมัน ดังนั้นหากคุณใช้คำสั่งใด ๆ ที่มี a %อยู่ (เช่นข้อกำหนดคุณสมบัติการจัดรูปแบบของคำสั่ง date) คุณจะต้องหลีกเลี่ยง

นั่นและ gotchas ดีๆอื่น ๆ ที่นี่:
http://www.pantz.org/software/cron/croninfo.html


นี่คือสิ่งที่ทำให้งาน Cron ของฉันล้มเหลวในสัปดาห์ที่ผ่านมา ในที่สุดก็คิดออกว่าวันที่ของฉันไม่ได้มีตัวละครหลบหนี (แบ็กสแลชสำหรับคนอื่น ๆ ที่กำลังมองหาตัวละครที่หลบหนี) เย้!
Valien


25

Cron กำลังเรียกใช้สคริปต์ซึ่งไม่สามารถเรียกใช้งานได้

เมื่อเรียกใช้chmod +x /path/to/scripสคริปต์จะสามารถเรียกใช้งานได้และควรแก้ไขปัญหานี้


5
นั่นไม่ใช่สิ่งที่ไม่ซ้ำกันcronและสามารถติดตามได้อย่างง่ายดายโดยเพียงแค่พยายามเรียกใช้/path/to/scriptจากบรรทัดคำสั่ง
Adam Matan

4
หากคุณคุ้นเคยกับการเรียกใช้งานสคริปต์ด้วย. scriptnameหรือsh scriptnameหรือbash scriptnameสิ่งนี้จะกลายเป็นcronปัญหาเฉพาะ
Eliah Kagan

24

เป็นไปได้ว่ารหัสผ่านของผู้ใช้หมดอายุ แม้แต่รหัสผ่านของรูทก็สามารถหมดอายุ คุณสามารถtail -f /var/log/cron.logและคุณจะเห็น cron ล้มเหลวด้วยรหัสผ่านหมดอายุ คุณสามารถตั้งรหัสผ่านให้ไม่มีวันหมดอายุโดยทำสิ่งนี้:passwd -x -1 <username>

ในบางระบบ (Debian, Ubuntu) การบันทึกสำหรับ cron จะไม่เปิดใช้งานตามค่าเริ่มต้น ใน/etc/rsyslog.confหรือ/etc/rsyslog.d/50-default.confบรรทัด:

# cron.*                          /var/log/cron.log

ควรได้รับการแก้ไข ( sudo nano /etc/rsyslog.conf) ไม่ใส่เครื่องหมายข้อคิดเห็นเป็น:

cron.*                          /var/log/cron.log

หลังจากนั้นคุณต้องรีสตาร์ท rsyslog ผ่าน

/etc/init.d/rsyslog restart

หรือ

service rsyslog restart 

ที่มา: เปิดใช้งานการบันทึก crontab ใน Debian Linux

ในบางระบบ (Ubuntu) ไฟล์บันทึกแยกต่างหากสำหรับ cron ไม่ได้เปิดใช้งานตามค่าเริ่มต้น แต่บันทึกที่เกี่ยวข้องกับ cron ปรากฏในไฟล์ syslog หนึ่งอาจใช้

cat /var/log/syslog | grep cron -i

เพื่อดูข้อความที่เกี่ยวข้องกับ cron


ฉันมี Debian (เสียงดัง) แต่ไม่มี /etc/init.d/rsyslog, inetutils-syslogd และ sysklogd เท่านั้น ฉันต้องติดตั้งบางอย่างหรือเริ่มใหม่จากหนึ่งในสองเครื่องหรือไม่
hgoebl

18

หาก cronjob ของคุณเรียกใช้แอพ GUI คุณต้องบอกพวกเขาว่าควรใช้ DISPLAY

ตัวอย่าง: Firefox เปิดตัวพร้อม cron

สคริปต์ของคุณควรมีexport DISPLAY=:0บางที่


aplay ต้องการอันนี้ด้วยเหตุผลบางอย่าง ขอบคุณ
IljaBek

* * * * * export DISPLAY=:0 && <command>
LoMaPh

15

ปัญหาการอนุญาตค่อนข้างพบได้บ่อยฉันกลัว

โปรดทราบว่าวิธีแก้ไขปัญหาทั่วไปคือการดำเนินการทุกอย่างโดยใช้ crontab ของรูทซึ่งบางครั้งเป็นแนวคิดที่ไม่ดีจริงๆ การตั้งค่าการอนุญาตที่เหมาะสมเป็นปัญหาที่ถูกมองข้ามเป็นส่วนใหญ่


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

14

การอนุญาตตาราง cron ที่ไม่ปลอดภัย

ตาราง cron ถูกปฏิเสธหากการอนุญาตไม่ปลอดภัย

sudo service cron restart
grep -i cron /var/log/syslog|tail -2
2013-02-05T03:47:49.283841+01:00 ubuntu cron[49906]: (user) INSECURE MODE (mode 0600 expected) (crontabs/user)

ปัญหาได้รับการแก้ไขด้วย

# correct permission
sudo chmod 600 /var/spool/cron/crontabs/user
# signal crond to reload the file
sudo touch /var/spool/cron/crontabs

ก่อนอื่นฉันคิดออกเองแล้วฉันก็พบคำตอบของคุณ! ยังคงขอบคุณมาก! ในกรณีของฉันฉันได้ย้อนกลับ / เรียกคืน crontabs บางอย่างใน / var / spool / cron / crontabs ผ่าน SVN ซึ่งเปลี่ยนสิทธิ์!
alfonx

12

สคริปต์มีความไวต่อตำแหน่ง สิ่งนี้เกี่ยวข้องกับการใช้พา ธ สัมบูรณ์ในสคริปต์เสมอ แต่ก็ไม่เหมือนกัน งาน cron ของคุณอาจต้องไปcdยังไดเรกทอรีเฉพาะก่อนที่จะทำงานเช่นงาน rake ในแอปพลิเคชั่น Rails อาจต้องอยู่ในรูทแอปพลิเคชันเพื่อให้ Rake ค้นหางานที่ถูกต้องไม่ต้องพูดถึงการกำหนดค่าฐานข้อมูลที่เหมาะสม ฯลฯ

ดังนั้นรายการ crontab ของ

23 3 * * * /usr/bin/rake db:session_purge RAILS_ENV=production

จะดีกว่า

23 3 * * * cd / var / www / การผลิต / ปัจจุบัน && / usr / bin / rake db: session_purge RAILS_ENV = การผลิต

หรือเพื่อให้รายการ crontab ง่ายขึ้นและเปราะน้อยลง:

23 3 * * * /home/<user>/scripts/session-purge.sh

ด้วยรหัสต่อไปนี้ใน/home/<user>/scripts/session-purge.sh:

cd / var / www / การผลิต / ปัจจุบัน
/ usr / bin / rake db: session_purge RAILS_ENV = การผลิต

1
หากสคริปต์ที่ถูกเรียกใช้จาก cron ถูกเขียนในภาษาที่ตีความเช่น PHP คุณอาจต้องตั้งค่าไดเรกทอรีการทำงานในสคริปต์เอง ตัวอย่างเช่นใน PHP: chdir(dirname(__FILE__));
Evan Donovan

เพิ่งถูกจับไปกับสคริปต์นี้: สคริปต์เคยอยู่ในรากของโฮมไดเร็กตอรี่ของฉัน, แต่จากนั้นฉันย้ายมัน (และอัปเดต crontab) และไม่รู้ว่าทำไมมันไม่ทำงาน. ปรากฎว่าสคริปต์กำลังใช้พา ธ สัมพัทธ์โดยสมมติว่ามันสัมพันธ์กับตำแหน่งของสคริปต์ แต่ในความเป็นจริงแล้วสัมพันธ์กับรูทของโฮมไดเร็กตอรี่ของฉันเพราะนั่นคือไดเร็กตอรี่ที่ทำงานซึ่ง cron ใช้อยู่ ทำงานเมื่อมันอยู่ในรากของไดเรกทอรีบ้านของฉัน (เพราะคาดว่าไดเรกทอรีการทำงานสคริปต์และมันเป็นจริงการทำงานเพียงแค่เกิดขึ้นให้ตรง)
Micheal Johnson

11

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

รูปแบบข้อกำหนดคุณสมบัติงาน cron แตกต่างกันระหว่างไฟล์ crontab ของผู้ใช้ (/ var / spool / cron / ชื่อผู้ใช้หรือ / var / spool / cron / crontabs / ชื่อผู้ใช้) และระบบ crontab ( /etc/crontabและไฟล์ใน/etc/cron.d)

crontabs ของระบบมีฟิลด์ 'ผู้ใช้' ที่ถูกต้องก่อนที่จะเรียกใช้คำสั่ง

สิ่งนี้จะทำให้เกิดข้อผิดพลาดในการระบุสิ่งต่าง ๆ เช่นgeorge; command not foundเมื่อคุณย้ายคำสั่งออกไป/etc/crontabหรือไฟล์/etc/cron.dเข้าไปในไฟล์ crontab ของผู้ใช้

ในทางกลับกัน cron จะส่งข้อผิดพลาดเหมือน/usr/bin/restartxyz is not a valid usernameหรือคล้ายกันเมื่อเกิดการย้อนกลับ


10

สคริปต์ cron กำลังเรียกใช้คำสั่งด้วย --verbose

ฉันมีสคริปต์ cron ล้มเหลวเพราะฉันอยู่ในโหมดอัตโนมัติในขณะที่พิมพ์สคริปต์และฉันรวมตัวเลือก --verbose:

#!/bin/bash
some commands
tar cvfz /my/archive/file.tar.gz /my/shared/directory
come more commands

สคริปต์รันได้ดีเมื่อเรียกใช้จากเชลล์ แต่ล้มเหลวเมื่อรันจาก crontab เนื่องจากเอาต์พุต verbose ไปที่ stdout เมื่อรันจาก shell แต่ไม่มีที่ใดเมื่อรันจาก crontab แก้ไขการลบ 'v' ได้ง่าย:

#!/bin/bash
some commands
tar cfz /my/archive/file.tar.gz /my/shared/directory
some more commands

5
ทำไมสิ่งนี้ทำให้เกิดความล้มเหลว ปัญหาบัฟเฟอร์ใช่ไหม
Adam Matan

เอาท์พุทหรือข้อผิดพลาดใด ๆ trriggred ผ่านงาน cron เป็น gooing ที่จะส่งไปยัง mailbox.So ของคุณเราไม่ควรลืมที่จะดูแลเกี่ยวกับข้อผิดพลาด / output.We สามารถเปลี่ยนเส้นทางไปยังไฟล์หรือ / dev / null
Nischay

10

สาเหตุที่พบบ่อยที่สุดที่ฉันเห็น cron ล้มเหลวในตารางที่ระบุไว้ไม่ถูกต้อง มันต้องใช้เวลาการปฏิบัติเพื่อระบุงานที่กำหนดไว้สำหรับ 23:15 เป็น15 23 * * *แทน หรือ* * 11 15 * 11 15 * * *วันของสัปดาห์สำหรับงานหลังเที่ยงคืนยังได้รับสับสน MF คือหลังเที่ยงคืนไม่ได้2-6 1-5วันที่ที่ระบุมักเป็นปัญหาเนื่องจากเราไม่ค่อยใช้พวกเขา* * 3 1 *ไม่ใช่วันที่ 3 มีนาคม หากคุณไม่แน่ใจว่าตรวจสอบตาราง cron ออนไลน์ของคุณที่https://crontab.guru/

หากการทำงานของคุณกับแพลตฟอร์มที่แตกต่างกันโดยใช้ตัวเลือกที่ไม่ได้รับการสนับสนุนเช่น2/3ข้อกำหนดเวลาอาจทำให้เกิดความล้มเหลวได้ นี่เป็นตัวเลือกที่มีประโยชน์มาก แต่ไม่สามารถใช้ได้ในระดับสากล ฉันได้ทำงานยังข้ามปัญหาเกี่ยวกับรายชื่อเหมือนหรือ1-51,3,5

การใช้พา ธ ที่ไม่มีเงื่อนไขทำให้เกิดปัญหาเช่นกัน เส้นทางเริ่มต้นมักจะเป็น/bin:/usr/binคำสั่งมาตรฐานเท่านั้นที่จะทำงาน ไดเรกทอรีเหล่านี้มักจะไม่มีคำสั่งที่ต้องการ สิ่งนี้มีผลกับสคริปต์โดยใช้คำสั่งที่ไม่ได้มาตรฐาน ตัวแปรสภาพแวดล้อมอื่นอาจหายไปเช่นกัน

การใช้ crontab ที่มีอยู่เดิมทำให้ฉันมีปัญหา ตอนนี้ฉันโหลดจากการคัดลอกไฟล์ สิ่งนี้สามารถกู้คืนได้จาก crontab ที่มีอยู่โดยใช้crontab -lถ้ามันถูกอุดตัน ฉันเก็บสำเนา crontab ไว้ใน ~ / bin # EOFมันเป็นความเห็นตลอดและจบลงด้วยเส้น นี่คือโหลดใหม่ทุกวันจากรายการ crontab เช่น:

#! / usr / bin / crontab
# โหลด crontab นี้ใหม่
#
54 12 * * * $ {HOME} / bin / crontab

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

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

ไม่ค่อยฉันมีคำสั่งที่ต้องป้อนข้อมูลผู้ใช้ สิ่งเหล่านี้ล้มเหลวภายใต้ crontab แม้ว่าบางอย่างจะทำงานกับการเปลี่ยนเส้นทางอินพุต


3
สิ่งนี้ครอบคลุมสามปัญหาที่แยกจากกัน พวกเขาสามารถแบ่งออกเป็นคำตอบแยกกันได้หรือไม่?
Eliah Kagan

9
คุณอธิบายได้ไหมว่า30 23 * * * แปลไปเป็นอย่างไร?
JYelton

@JYelton 15 23 * * *นั่นเป็นความผิดพลาดอย่างเห็นได้ชัดก็ควรจะ ถูกต้องแล้ว
Melebius

7

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

หากระบบใช้ PAM และบัญชีถูกล็อคสิ่งนี้สามารถหยุดการทำงานของ cronjob ได้ (ฉันได้ทดสอบสิ่งนี้กับ Solaris แต่ไม่ใช่ใน Ubuntu)

คุณอาจพบข้อความเช่นนี้ใน / var / adm / ข้อความ:

24 Oct 07:51:00 mybox cron [29024]: [ID 731128 auth.notice] pam_unix_account: cron พยายามตรวจสอบ myuser บัญชีที่ถูกล็อคจากโฮสต์ท้องถิ่น
24 ต.ค. 07:52:00 mybox cron [29063]: [ID 731128 auth.notice] pam_unix_account: cron พยายามตรวจสอบ myuser บัญชีที่ล็อคจากโฮสต์ท้องถิ่น
24 Oct 07:53:00 mybox cron [29098]: [ID 731128 auth.notice] pam_unix_account: cron พยายามตรวจสอบ myuser บัญชีที่ล็อคจากโฮสต์ท้องถิ่น
24 Oct 07:54:00 mybox cron [29527]: [ID 731128 auth.notice] pam_unix_account: cron พยายามตรวจสอบ myuser บัญชีที่ถูกล็อคจากโฮสต์ในพื้นที่

สิ่งที่คุณต้องทำคือเรียกใช้:

# passwd -u <USERNAME>

เป็น root เพื่อปลดล็อคบัญชีและ crontab ควรทำงานอีกครั้ง


7

หากคุณมีคำสั่งเช่นนี้:

* * * * * /path/to/script >> /tmp/output

และมันไม่ทำงานและคุณไม่สามารถเห็นผลลัพธ์ใด ๆ ก็อาจไม่ได้หมายความว่า cron ไม่ทำงาน สคริปต์อาจใช้งานไม่ได้และเอาต์พุตจะเป็นstderrซึ่งไม่ได้ผ่านไปยัง / tmp / output ตรวจสอบในกรณีนี้ไม่ได้โดยจับผลลัพธ์นี้เช่นกัน:

* * * * * /path/to/script >> /tmp/output 2>&1

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


3

=== การแจ้งเตือนนักเทียบท่า ===

หากคุณใช้นักเทียบท่า

ฉันคิดว่ามันเหมาะสมที่จะเพิ่มว่าฉันไม่สามารถจัดการให้ cron ทำงานในพื้นหลังได้

ในการรันงาน cron ภายในคอนเทนเนอร์ฉันใช้หัวหน้างานและวิ่งcron -fพร้อมกับกระบวนการอื่น

แก้ไข: ปัญหาอื่น - ฉันยังไม่ได้จัดการเพื่อให้มันทำงานเมื่อใช้คอนเทนเนอร์ด้วยเครือข่าย HOST ดูปัญหานี้ได้ที่นี่: https://github.com/phusion/baseimage-docker/issues/144



3

ฉันกำลังเขียนเชลล์สคริปต์การติดตั้งที่สร้างสคริปต์อื่นเพื่อล้างข้อมูลธุรกรรมเก่าจากฐานข้อมูล เป็นส่วนหนึ่งของงานมันต้องกำหนดค่าcronงานรายวันให้ทำงานตามอำเภอใจเมื่อโหลดฐานข้อมูลต่ำ

ฉันสร้างไฟล์mycronjobด้วยตารางเวลา cron ชื่อผู้ใช้ & คำสั่งและคัดลอกไปยัง/etc/cron.dไดเรกทอรี สอง gotchas ของฉัน:

  1. mycronjob ไฟล์ต้องเป็นเจ้าของโดย root เพื่อให้ทำงาน
  2. ฉันต้องตั้งค่าการอนุญาตของไฟล์เป็น 644 - 664 จะไม่ทำงาน

ปัญหาการอนุญาตจะปรากฏ/var/log/syslogเป็นสิ่งที่คล้ายกับ:

Apr 24 18:30:01 ip-11-22-33-44 cron[40980]: (*system*) INSECURE MODE (group/other writable) (/etc/crontab)
Apr 24 18:30:01 ip-11-22-33-44 cron[40980]: (*system*) INSECURE MODE (group/other writable) (/etc/cron.d/user)

บรรทัดแรกหมายถึงการยื่นและต่อมาไปยังไฟล์ที่ผมวางไว้ภายใต้/etc/crontab/etc/cront.d


2

บรรทัดที่เขียนด้วยวิธี crontab ไม่เข้าใจ จะต้องมีการเขียนอย่างถูกต้อง นี่คือCrontabHowTo


1
สิ่งนี้จะดีบั๊กได้อย่างไร
Adam Matan

การตรวจสอบบันทึกข้อผิดพลาดของ cron เป็นวิธีที่พบได้บ่อยที่สุด IIRC 'crontab -e' ทำไวยากรณ์แยกวิเคราะห์หลังจากที่คุณแก้ไขไฟล์เช่นกัน - แต่นั่นอาจไม่เป็นสากล
pbr

2

Cron daemon สามารถทำงานได้ แต่ไม่สามารถใช้งานได้จริง ลองรีสตาร์ท cron:

sudo /etc/init.d/cron restart

3
ฉันไม่เคยเห็นเคสนี้ในการผลิต ไม่ได้หมายความว่ามันไม่ได้เกิดขึ้น - เพียงแค่ฉันไม่ได้เห็นมันใน 30 ปีที่ฉันใช้ UNIX และ Linux Cron แข็งแรงทนทาน
pbr

1
ฉันไม่แน่ใจ แต่ฉันคิดว่านี่เกิดขึ้นกับฉันจริงๆ ฉันลองpidofcron และไม่ได้อะไรเลย พยายามใช้serviceยูทิลิตี้และบอกว่า cron กำลังทำงานอยู่ เพิ่งรันคำสั่งนี้แล้ววิ่งpidofอีกครั้งและฉันก็ได้ผลลัพธ์
คอลลีน

2

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

# m h dom mon dow command

* * */2  *   *  /some/shell/script

ในขณะที่ / etc / crontab จะเป็น:

# m h dom mon dow user   command

* * */2  *   *  jdoe   /some/shell/script

ดังนั้นทำไมคุณจะทำหลัง ขึ้นอยู่กับว่าคุณต้องการกำหนดสิทธิ์ของคุณอย่างไรมันอาจซับซ้อนมาก ฉันได้เขียนสคริปต์เพื่อทำให้งานโดยอัตโนมัติสำหรับผู้ใช้ที่ไม่เข้าใจความซับซ้อนหรือไม่ต้องการยุ่งกับงานน่าเบื่อหน่าย ด้วยการตั้งค่าการอนุญาต--x------ฉันสามารถทำให้สคริปต์ทำงานได้โดยที่พวกเขาไม่สามารถอ่าน (และอาจเปลี่ยนแปลงได้โดยไม่ตั้งใจ) อย่างไรก็ตามฉันอาจต้องการเรียกใช้คำสั่งนี้กับคนอื่น ๆ จากหลายไฟล์ (ทำให้การดูแลรักษาง่ายขึ้น) แต่ให้แน่ใจว่าไฟล์ที่ส่งออกนั้นได้รับมอบหมายให้เป็นเจ้าของที่ถูกต้อง การทำเช่นนั้น (อย่างน้อยใน Ubuntu 10.10) จะทำให้ทั้งสองไม่สามารถอ่านไฟล์และดำเนินการรวมทั้งปัญหาที่กล่าวถึงข้างต้นด้วยการใส่จุดใน / etc / crontab (ซึ่งสนุกพอทำให้ไม่มีข้อผิดพลาดเมื่อผ่านcrontab -e) .

ตัวอย่างเช่นฉันเคยเห็นอินสแตนซ์ที่sudo crontab -eใช้ในการเรียกใช้สคริปต์ที่มีสิทธิ์ใช้งานรูทพร้อมด้วยคำสั่งchown username file_outputในเชลล์สคริปต์ เลอะเทอะ แต่มันได้ผล IMHO ตัวเลือกที่ดีกว่าคือการใส่/etc/crontabชื่อผู้ใช้และการอนุญาตที่เหมาะสมดังนั้นfile_outputไปยังสถานที่และเจ้าของที่ถูกต้อง


"การทำเช่นนั้น (อย่างน้อยใน Ubuntu 10.10) จะทำให้ทั้งสองไม่สามารถอ่านไฟล์และดำเนินการ ..... " ฉันควรชี้แจง: / etc / crontab (โดยค่าเริ่มต้น) ต้องอ่านและดำเนินการสิทธิ์ในขณะที่คุณสามารถ เรียกใช้ "sudo crontab -e" เพื่อสร้าง cronjob ซึ่งแทนที่ทั้งความต้องการสิทธิ์ "w" และปัญหาเกี่ยวกับส่วนขยายเช่น ".sh" ฉันไม่มีเวลาดึงรหัส cron และตรวจสอบว่าทำไมงานนี้ถึงมีรายละเอียดเท่าที่ฉันสังเกตเห็น
โรคเรื้อนของสุนัข

2

การสร้างสิ่งที่ Aaron Peart กล่าวถึงเกี่ยวกับโหมด verbose บางครั้งสคริปต์ที่ไม่ได้อยู่ในโหมด verbose จะเริ่มต้นได้ แต่จะไม่เสร็จสิ้นหากพฤติกรรมเริ่มต้นของคำสั่งที่รวมไว้คือการส่งออกบรรทัดหรือมากกว่าไปยังหน้าจอเมื่อ proc เริ่มทำงาน ตัวอย่างเช่นฉันเขียนสคริปต์สำรองสำหรับอินทราเน็ตของเราซึ่งใช้ curl ยูทิลิตี้ที่ดาวน์โหลดหรืออัพโหลดไฟล์ไปยังเซิร์ฟเวอร์ระยะไกลและค่อนข้างมีประโยชน์หากคุณสามารถเข้าถึงไฟล์ระยะไกลผ่าน HTTP ได้เท่านั้น การใช้ 'curl http://something.com/somefile.xls ' ทำให้สคริปต์ที่ฉันเขียนหยุดทำงานและไม่เสร็จสมบูรณ์เพราะมันพ่นบรรทัดใหม่ตามด้วยบรรทัดความคืบหน้า ฉันต้องใช้การตั้งค่าสถานะเงียบ (-s) เพื่อบอกว่าจะไม่ส่งออกข้อมูลใด ๆ และเขียนรหัสของตัวเองเพื่อจัดการหากไฟล์ไม่สามารถดาวน์โหลดได้


1
/dev/nullสำหรับโปรแกรมที่ไม่ได้มีโหมดเงียบคุณสามารถเปลี่ยนเส้นทางการส่งออกของพวกเขาไป ตัวอย่างเช่น: some-command > /dev/nullสิ่งนี้จะเปลี่ยนเส้นทางเฉพาะเอาต์พุตมาตรฐานและไม่ใช่เอาต์พุตข้อผิดพลาด (ซึ่งโดยปกติคือสิ่งที่คุณต้องการเนื่องจากคุณต้องการได้รับการแจ้งข้อผิดพลาด) some-command &> /dev/nullเมื่อต้องการเปลี่ยนเส้นทางออกข้อผิดพลาดมากเกินไปใช้
Eliah Kagan

ใช่นั่นเป็นความคิดแรกของฉันเมื่อเขียนสคริปต์ดังกล่าวข้างต้น ฉันลืมว่าทำไมฉันไม่ได้ใช้สิ่งนั้นอาจเป็นพฤติกรรมที่ไม่ได้มาตรฐานซึ่งหลีกเลี่ยงวิธีแก้ปัญหาดังกล่าว ฉันรู้ว่าโหมด verbose / interactive เป็นค่าเริ่มต้นในบางคำสั่ง (ฉันกำลังมองหาคุณ, scp!) ซึ่งหมายความว่าคุณต้อง hadle กล่าวว่าเอาต์พุตเพื่อการทำงานที่ราบรื่นของเชลล์สคริปต์
โรคเรื้อนของสุนัข

2

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

SOME_DIR=/var/log
MY_LOG_FILE=${SOME_LOG}/some_file.log

BIN_DIR=/usr/local/bin
MY_EXE=${BIN_DIR}/some_executable_file

0 10 * * * ${MY_EXE} some_param >> ${MY_LOG_FILE}

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

แต่คุณต้องกำหนดตัวแปรสภาพแวดล้อมทั้งหมดของคุณให้ตรง:

SOME_DIR=/var/log
MY_LOG_FILE=/var/log/some_file.log

BIN_DIR=/usr/local/bin
MY_EXE=/usr/local/bin/some_executable_file

0 10 * * * ${MY_EXE} some_param >> ${MY_LOG_FILE}

2

เมื่องานถูกเรียกใช้ภายใน cron stdin จะถูกปิด โปรแกรมที่ทำหน้าที่แตกต่างกันขึ้นอยู่กับว่า stdin พร้อมใช้งานหรือไม่จะทำงานแตกต่างกันระหว่างเซสชันของเชลล์และใน cron

ตัวอย่างคือโปรแกรมgoaccessสำหรับวิเคราะห์ไฟล์บันทึกของเว็บเซิร์ฟเวอร์ สิ่งนี้ไม่ทำงานใน cron:

goaccess -a -f /var/log/nginx/access.log > output.html

และgoaccessแสดงหน้าช่วยเหลือแทนการสร้างรายงาน ในเปลือกนี้สามารถทำซ้ำด้วย

goaccess -a -f /var/log/nginx/access.log > output.html < /dev/null

การแก้ไขgoaccessคือการทำให้อ่านล็อกจาก stdin แทนที่จะอ่านจากไฟล์ดังนั้นวิธีแก้ไขคือเปลี่ยนรายการ crontab เป็น

cat /var/log/nginx/access.log | goaccess -a > output.html

2

ในกรณีของฉัน cron และ crontab มีเจ้าของที่แตกต่างกัน

ไม่ทำงานฉันมีสิ่งนี้:

User@Uva ~ $ ps -ef | grep cron | grep -v grep
User    2940    7284 pty1     19:58:41 /usr/bin/crontab
SYSTEM   11292     636 ?        22:14:15 /usr/sbin/cro 

โดยทั่วไปฉันต้องรัน cron-config และตอบคำถามอย่างถูกต้อง มีจุดที่ฉันต้องป้อนรหัสผ่านผู้ใช้ Win7 สำหรับบัญชี 'ผู้ใช้' ของฉัน จากการอ่านที่ฉันทำดูเหมือนว่านี่เป็นปัญหาด้านความปลอดภัยที่อาจเกิดขึ้น แต่ฉันเป็นผู้ดูแลระบบเพียงรายเดียวในเครือข่ายในบ้านเดียวดังนั้นฉันจึงตัดสินใจว่ามันใช้ได้

นี่คือลำดับของคำสั่งที่ทำให้ฉันไป:

User@Uva ~ $ cron-config
The cron daemon can run as a service or as a job. The latter is not recommended.
Cron is already installed as a service under account LocalSystem.
Do you want to remove or reinstall it? (yes/no) yes
OK. The cron service was removed.

Do you want to install the cron daemon as a service? (yes/no) yes
Enter the value of CYGWIN for the daemon: [ ] ntsec

You must decide under what account the cron daemon will run.
If you are the only user on this machine, the daemon can run as yourself.
   This gives access to all network drives but only allows you as user.
To run multiple users, cron must change user context without knowing
  the passwords. There are three methods to do that, as explained in
  http://cygwin.com/cygwin-ug-net/ntsec.html#ntsec-nopasswd1
If all the cron users have executed "passwd -R" (see man passwd),
  which provides access to network drives, or if you are using the
  cyglsa package, then cron should run under the local system account.
Otherwise you need to have or to create a privileged account.
  This script will help you do so.
Do you want the cron daemon to run as yourself? (yes/no) no

Were the passwords of all cron users saved with "passwd -R", or
are you using the cyglsa package ? (yes/no) no

Finding or creating a privileged user.
The following accounts were found: 'cyg_server' .
This script plans to use account cyg_server.
Do you want to use another privileged account name? (yes/no) yes
Enter the other name: User

Reenter: User


Account User already exists. Checking its privileges.
INFO: User is a valid privileged account.
INFO: The cygwin user name for account User is User.

Please enter the password for user 'User':
Reenter:
Running cron_diagnose ...
... no problem found.

Do you want to start the cron daemon as a service now? (yes/no) yes
OK. The cron daemon is now running.

In case of problem, examine the log file for cron,
/var/log/cron.log, and the Windows event log (using /usr/bin/cronevents)
for information about the problem cron is having.

Examine also any cron.log file in the HOME directory
(or the file specified in MAILTO) and cron related files in /tmp.

If you cannot fix the problem, then report it to cygwin@cygwin.com.
Please run the script /usr/bin/cronbug and ATTACH its output
(the file cronbug.txt) to your e-mail.

WARNING: PATH may be set differently under cron than in interactive shells.
         Names such as "find" and "date" may refer to Windows programs.


User@Uva ~ $ ps -ef | grep cron | grep -v grep
    User    2944   11780 ?        03:31:10 /usr/sbin/cron
    User    2940    7284 pty1     19:58:41 /usr/bin/crontab

User@Uva ~ $

1
แม้ว่าจะได้รับการบันทึกไว้อย่างดี แต่ดูเหมือนว่าเป็นจุดเฉพาะของ Cygwin มันเป็นของ Askubuntu จริงๆเหรอ?
sxc731

2

บนเซิร์ฟเวอร์ RHEL7 ของฉันงานรูท cron จะทำงาน แต่งานของผู้ใช้จะไม่ ฉันพบว่าไม่มีไดเรกทอรีบ้านงานจะไม่ทำงาน (แต่คุณจะเห็นข้อผิดพลาดที่ดีใน / var / log / cron) เมื่อฉันสร้างโฮมไดเร็กตอรีปัญหาได้รับการแก้ไข


2

หากคุณแก้ไขไฟล์ crontab โดยใช้ windows editor (ผ่าน samba หรืออะไรบางอย่าง) และมันถูกแทนที่ด้วยบรรทัดใหม่ด้วย \ n \ r หรือเพียงแค่ \ r cron จะไม่ทำงาน

นอกจากนี้หากคุณใช้ /etc/cron.d/* และไฟล์ใดไฟล์หนึ่งมี a \ r อยู่ cron จะเลื่อนไปตามไฟล์ต่างๆและหยุดเมื่อไฟล์ดังกล่าวเจอไฟล์ที่ไม่ดี ไม่แน่ใจว่าเป็นปัญหาหรือไม่

ใช้:

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