ฉันจะสร้าง crontab ผ่านสคริปต์ได้อย่างไร


153

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

เป็นไปได้ที่จะทำเช่นนั้น?




หากคุณต้องการแก้ไขหรือลบรายการ crontab ดูโซลูชันของฉันด้านล่าง
Brian Smith

คำตอบ:


11

งาน Cron มักจะถูกเก็บไว้ในไฟล์ต่อผู้ใช้ภายใต้ /var/spool/cron

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


20
การแก้ไขไฟล์โดยตรงใน / var / spool / cron จะถูกดึงออกมา ในความเป็นจริงถ้าคุณดูไฟล์ที่นั่นพวกเขามักจะมีคำเตือนเช่น "ห้ามแก้ไขไฟล์นี้" เป็นบรรทัดแรก
Jared

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

47
เลื่อนลงเพื่อหาคำตอบที่แท้จริง
จอห์นเรด

1
ในความคิดของฉันคำตอบนี้ดีกว่า: stackoverflow.com/a/610860/2681752
galaux

2
ฉันใช้วิธีนี้และรู้สึกเสียใจ บน RHEL ไดเรกทอรี / var / spool / cron ไม่สามารถใช้งานได้ในโลกดังนั้นผู้ใช้จึงไม่สามารถสำรวจไดเรกทอรีและแก้ไขไฟล์ด้วยตนเองได้ หากคุณสร้าง / var / spool / cron world executable ระบบท้องถิ่นที่เป็นมิตรของคุณจะคลั่งไคล้คุณรวมถึงการเปลี่ยนแปลงการอนุญาตสามารถเขียนทับได้หากแพ็คเกจ cronie ติดตั้งใหม่หรืออัปเดต
functionvoid

384

ต่อไปนี้เป็นหนึ่งในสายการบินที่ไม่ได้ใช้ / ต้องการงานใหม่ให้อยู่ในไฟล์:

(crontab -l 2>/dev/null; echo "*/5 * * * * /path/to/job -with args") | crontab -

2>/dev/nullจึงเป็นสิ่งสำคัญที่คุณไม่ได้รับno crontab for usernameข้อความว่าบาง nixes * ผลิตถ้ามีอยู่ในขณะนี้ไม่มีรายการ crontab


14
นี่ควรเป็นคำตอบที่ยอมรับได้ เพียงแค่ต้องมีวิธีในขณะนี้เพื่อตรวจสอบว่าซับหนึ่งที่ผมตั้งใจที่จะเพิ่มที่มีอยู่แล้วหรือไม่ ...
ChrisPrime

7
... โอ้เดี๋ยวก่อนต่อไปนี้เป็นวิธีการตรวจสอบว่ามีบางสิ่งอยู่ใน crontab ของผู้ใช้ก่อนที่ฉันจะเพิ่มด้วยสคริปต์: stackoverflow.com/a/14451184/3686125
ChrisPrime

1
หากสคริปต์นี้มีวัตถุประสงค์เพื่อเป็นคำสั่งที่จะทำซ้ำและแก้ไขงาน cron ที่มีอยู่มันอาจจะดีที่จะแทนที่บรรทัดที่มีอยู่ใน crontab เครื่องหมายหลายตัวสามารถใช้ในการควบคุมงาน cron ที่แตกต่างกัน (control-marker-1, control-marker-2, etc ... ): (crontab -l 2> / dev / null | grep -v control-marker-1; echo '* / 5 * * * * / เส้นทาง / ถึง / งานด้วย args # control-marker-1') | crontab -
พ่อครัว

7
ฉันพบว่านี่เป็นการลบรายการ crontab ที่มีอยู่และฉันจำเป็นต้องใช้ผู้ใช้อื่น (root) ดังนั้นฉันจึงใช้สิ่งต่อไปนี้เพื่อรักษารายการที่มีอยู่: echo -e "$(sudo crontab -u root -l)\n* * * * * echo hello > /home/danny/temp.log 2>&1" | sudo crontab -u root -หวังว่านี่จะช่วยให้ใครบางคน
Danny

60

สำหรับผู้ใช้ crontabs (รวมถึงรูท) คุณสามารถทำสิ่งต่อไปนี้:

crontab -l -u user | cat - filename | crontab -u user -

โดยที่ไฟล์ชื่อ "filename" มีรายการที่จะต่อท้าย นอกจากนี้คุณยังสามารถทำจัดการข้อความที่ใช้หรือเครื่องมืออื่นในสถานที่ของsed catคุณควรใช้crontabคำสั่งแทนการแก้ไขไฟล์โดยตรง

การดำเนินการที่คล้ายกันจะเป็น:

{ crontab -l -u user; echo 'crontab spec'; } | crontab -u user -

หากคุณกำลังแก้ไขหรือสร้าง crontabs ระบบสิ่งเหล่านั้นอาจได้รับการจัดการเช่นเดียวกับไฟล์ข้อความธรรมดา พวกเขาจะถูกเก็บไว้ใน/etc/cron.d, /etc/cron.hourly, /etc/cron.daily, /etc/cron.weekly, /etc/cron.monthlyไดเรกทอรีและไฟล์และ/etc/crontab/etc/anacrontab


ดูมีแนวโน้ม แต่ลองใช้แนวทางที่สอง (พร้อมecho) ฉันได้รับ "crontab: การใช้ผิดพลาด: ต้องระบุชื่อไฟล์เพื่อแทนที่" หน้าคน Cron แสดงไวยากรณ์เป็นcrontab [ -u user ] fileนั่นคือด้วยชื่อไฟล์บังคับ มีเคล็ดลับที่จะทำให้การยอมรับข้อมูล piped หรือไม่?
Mark Berry

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

29

ใน Ubuntu และ distros อื่น ๆ คุณสามารถใส่ไฟล์ลงใน/etc/cron.dไดเรกทอรีที่มีบรรทัดเดียวพร้อมกับรายการcrontab ที่ถูกต้อง ไม่จำเป็นต้องเพิ่มบรรทัดลงในไฟล์ที่มีอยู่

/etc/cron.dailyหากคุณเพียงแค่ต้องการสิ่งที่จะทำงานทุกวันเพียงแค่ใส่ไฟล์ลงใน ในทำนองเดียวกันคุณยังสามารถวางไฟล์ลง/etc/cron.hourly, และ/etc/cron.monthly/etc/cron.weekly


5
แต่คุณต้องรูทเพื่อทำสิ่งนี้
Keith

17

คำตอบที่ง่ายยิ่งขึ้นสำหรับคำถามของคุณคือ:

echo "0 1 * * * /root/test.sh" | tee -a /var/spool/cron/root

คุณสามารถตั้งค่า cronjobs บนเซิร์ฟเวอร์ระยะไกลได้ดังนี้:

#!/bin/bash
servers="srv1 srv2 srv3 srv4 srv5"
for i in $servers
  do
  echo "0 1 * * * /root/test.sh" | ssh $i " tee -a /var/spool/cron/root"
done

ใน Linux ที่ตั้งเริ่มต้นของไฟล์crontab /var/spool/cron/ที่นี่คุณสามารถค้นหาcrontabไฟล์ของผู้ใช้ทั้งหมด คุณเพียงแค่เพิ่มรายการ cronjob ของคุณต่อท้ายไฟล์ของผู้ใช้นั้น ๆ ในตัวอย่างด้านบนไฟล์ crontab ของผู้ใช้รูทจะถูกต่อท้ายด้วย cronjob เพื่อรัน/root/test.shทุกวันเวลา 1:00 น


นั่นจะเป็น/var/spool/cron/crontabs/rootบน Ubuntu
ÍhorMé

17

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

crontab [path to file]สามารถใช้เพื่อระบุ crontab ที่เก็บไว้ในไฟล์ เช่นcrontab -eนี้จะติดตั้งไฟล์หากไม่มีข้อผิดพลาด

ดังนั้นสคริปต์สามารถเขียนไฟล์แท็บ cron โดยตรงหรือเขียนลงในไฟล์ชั่วคราวและโหลดด้วยcrontab [path to temp file]คำสั่ง การบันทึกโดยตรงจะช่วยให้คุณไม่ต้องเขียนไฟล์ชั่วคราว แต่ก็หลีกเลี่ยงการตรวจสอบความปลอดภัย


2
สำหรับ noobs เช่นตัวฉันเองให้สังเกตว่ามันคือcrontab [path to file].. นี่เป็นตัวเลือกที่ดีที่สุดสำหรับฉันเพราะมันช่วยให้อ่านรหัสได้ง่ายขึ้น ฉันใช้ crontab เพื่อติดตามพัสดุและเปลี่ยนภาพพื้นหลังเดสก์ทอปของฉันด้วยสถานะ เมื่อฉันไม่ได้คาดหวังพัสดุมันไม่จำเป็นต้องตรวจสอบทุกชั่วโมง นั่นเป็นเหตุผลที่ฉันต้องการให้สคริปต์แก้ไขความถี่ cron โดยอัตโนมัติ
Rasmus

1
@Rasmus ฟังดูเหมือนสคริปต์ที่ยอดเยี่ยมฉันชอบที่จะขโมย มีโอกาสแบ่งปันผ่านทางส่วนสำคัญหรือคล้ายคลึงกันไหม?
cledoux

8

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

หนึ่งซับในของ Joe Casadonteนั้นสมบูรณ์แบบยกเว้นถ้าคุณทำงานด้วยset -eเช่นถ้าสคริปต์ของคุณถูกตั้งค่าให้ล้มเหลวเนื่องจากข้อผิดพลาดและถ้าไม่มี cronjobs ในกรณีนั้นหนึ่งซับจะไม่สร้าง cronjob แต่จะไม่หยุดสคริปต์ ความล้มเหลวเงียบสามารถทำให้เข้าใจผิดมาก

เหตุผลก็คือcrontab -lส่งคืนพร้อม1รหัสส่งคืนทำให้คำสั่งที่ตามมา ( echoไม่) ถูกเรียกใช้ ... ดังนั้นจึงไม่สร้าง cronjob แต่เนื่องจากพวกเขาจะถูกดำเนินการเป็น subprocess (เพราะวงเล็บ) พวกเขาจะไม่หยุดสคริปต์

(ที่น่าสนใจถ้าคุณเรียกใช้คำสั่งเดียวกันอีกครั้งมันจะทำงาน: เมื่อคุณดำเนินการcrontab -ครั้งเดียวcrontab -lก็ยังไม่มีอะไรออก แต่มันจะไม่กลับข้อผิดพลาดอีกต่อไป (คุณไม่ได้รับno crontab for <user>ข้อความอีกต่อไป) ดังนั้นต่อมาechoดำเนินการ และ crontab ถูกสร้างขึ้น)

ไม่ว่าในกรณีใด ๆ หากคุณใช้set -eงานสายจะต้อง:

(crontab -l 2>/dev/null || true; echo "*/5 * * * * /path/to/job -with args") | crontab -

ใช่คนนี้สมบูรณ์แบบมากยิ่งขึ้น
Yngve Sneen Lindal

7

เป็นการแก้ไขข้อเสนอแนะcrontab -l | crontab -: สิ่งนี้ไม่สามารถใช้ได้กับทุกระบบ ตัวอย่างเช่นฉันต้องเพิ่มงานในรูท crontab บนเซิร์ฟเวอร์หลายสิบเครื่องที่ใช้ SUSE เวอร์ชันเก่า (อย่าถามว่าทำไม) SUSEs เก่าเติมบรรทัดความคิดเห็นไปยังผลลัพธ์ของcrontab -lการทำที่crontab -l | crontab -ไม่ใช่ idempotent (Debian ตระหนักถึงปัญหานี้ใน manpage crontab และแก้ไขเวอร์ชัน Vixie Cron เพื่อแก้ไขพฤติกรรมเริ่มต้นของcrontab -l)

หากต้องการแก้ไข crontabs โดยทางโปรแกรมในระบบที่crontab -lเพิ่มความคิดเห็นคุณสามารถลองทำสิ่งต่อไปนี้:

EDITOR=cat crontab -e > old_crontab; cat old_crontab new_job | crontab -

EDITOR=catบอกให้ crontab ใช้catเป็นตัวแก้ไข (ไม่ใช่ค่าปริยายปกติ vi) ซึ่งไม่เปลี่ยนไฟล์ แต่คัดลอกไปที่ stdout แทน สิ่งนี้อาจยังคงล้มเหลวหากcrontab -คาดว่าอินพุตในรูปแบบแตกต่างจากcrontab -eเอาต์พุตใด อย่าพยายามแทนที่รอบสุดท้ายcrontab -ด้วยcrontab -e- มันจะไม่ทำงาน


4

ดี/etc/crontabเพียงไฟล์ ASCII เพื่อให้ง่ายที่สุดคือการเพียง

 echo "*/15 * * * *   root     date" >> /etc/crontab

ซึ่งจะเพิ่มงานซึ่งจะส่งอีเมลถึงคุณทุก 15 นาที ปรับแต่งเพื่อลิ้มรสและทดสอบผ่านทางgrepหรือวิธีการอื่น ๆ ไม่ว่าจะเพิ่มบรรทัดนั้นเพื่อให้ idempotent ของสคริปต์ของคุณ

บน Ubuntu et al, คุณยังสามารถวางไฟล์ใน/etc/cron.*ซึ่งเป็นที่ง่ายต่อการทำและการทดสอบหา --- รวมทั้งคุณจะไม่ยุ่งกับ (ระบบ) ไฟล์ config /etc/crontabเช่น


1
ฉันคิดว่าเทคนิค crond ไม่จำเป็นต้องตรวจสอบการเปลี่ยนแปลง crontab แม้ว่าในความเป็นจริงการใช้งานส่วนใหญ่ทำดังนั้นฉันขอแนะนำให้โทร crontab -e หลังจากนั้นเพื่อแยงมัน crontab -e ให้เกียรติตัวแปร EDITOR หากหน่วยความจำทำหน้าที่ดังนั้นให้ตั้งเป็น / bin / true ในขณะนั้นควรบังคับให้ crontab อ่านใหม่
Ulrich Schwarz

1
จริงบนระบบ Linux ล่าสุดใด ๆcrond จะตรวจสอบและแน่นอนมันจะทำบนแพลตฟอร์มที่ระบุไว้ของ OP
Dirk Eddelbuettel

เฉพาะในกรณีที่คุณรูทและต้องการให้สคริปต์ทำงานเป็นรูท นั่นอาจไม่เป็นที่พึงปรารถนาในเคส OPs
Keith

ไม่เช่นนั้นฉันมีรายการที่ไม่ใช่รูทจำนวนมากใน / etc / crontab คุณเพียงแค่ต้องการให้ sudo ต่อท้ายไฟล์ ยังไงก็ตามตามที่ฉันบอกไว้มี /etc/cron.*/ ด้วย แต่คุณต้องรูทเพื่อเขียนที่นั่น
Dirk Eddelbuettel

2

นี่คือวิธีการแก้ไข cron รายการโดยไม่ต้องแก้ไขไฟล์ cron โดยตรง (ซึ่งขมวดคิ้วอยู่)

crontab -l -u <user> | sed 's/find/replace/g' | crontab -u <user> -

หากคุณต้องการลบรายการ cron ให้ใช้สิ่งนี้:

crontab -l -u <user> | sed '/find/d' | crontab -u <user> -

ฉันรู้ว่านี่ไม่ใช่สิ่งที่ gaurav ร้องขอ แต่ทำไมไม่มีโซลูชั่นทั้งหมดในที่เดียว


1

ฉันได้เขียนเครื่องมือการปรับใช้ crontab ใน python: https://github.com/monklof/deploycron

pip install deploycron

ติดตั้ง crontab ของคุณง่ายมากซึ่งจะรวม crontab เข้ากับ crontab ที่มีอยู่ของระบบ

from deploycron import deploycron
deploycron(content="* * * * * echo hello > /tmp/hello")

1

มันเป็นวิธีการเพิ่มงาน cron เพิ่ม:

  ssh USER_NAME@$PRODUCT_IP nohup "echo '*/2 * * * * ping -c2 PRODUCT_NAME.com >> /var/www/html/test.html' | crontab -u USER_NAME -"
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.