find -delete ทำงานได้ดี แต่ไม่ใช่ cron


10

โปรดทราบ : ฉันได้อ่านคำถามที่คล้ายกันทั้งหมดแล้ว cron, พา ธ , ตัวแปร env และอื่น ๆ แต่ไม่พบใครที่เสนอวิธีแก้ปัญหาเฉพาะของฉัน


ฉันมีสคริปต์ที่ทำให้ MySQL ทิ้งและลบไฟล์เก่าแบบนี้:

/usr/bin/find "/home/bkp/dbdump" -name "*.gz" -mtime +5 -delete

( คำสั่งด้านบนได้รับการแก้ไขจากคำสั่งเดิมของฉันโดยคำแนะนำจากความคิดเห็น )

อย่างไรก็ตามไฟล์จะไม่ถูกลบเมื่อ cron รันสคริปต์นี้ ผู้ใช้ cron คือรูท

การดีบักโน้ต

  • ถ้าฉันเรียกใช้สคริปต์ด้วยตนเองซึ่งคำสั่งปรากฏขึ้นมันจะลบออกตามที่คาดไว้

  • หากฉันรันคำสั่ง find ด้านบนด้วยตัวเองจากบรรทัดคำสั่งในฐานะรูทคำสั่งจะลบมันตามที่คาดไว้ (และด้วย -print จะส่งคืนรายการไฟล์ที่เก่ากว่า 5 วันตามที่คาดไว้)

  • ฉันยังได้เพิ่มคำสั่งพา ธ ที่ชัดเจนไปยัง crontab ของรูท แต่
    นั่นไม่เปลี่ยนแปลงอะไรเลย

  • Cron ส่งข้อผิดพลาดไม่และถ้าฉันไปป์การดำเนินการค้นหาไปยังแฟ้มบันทึก
    ที่ว่างเปล่าหรือไม่ได้สร้างเลย

  • ฉันใช้เซิร์ฟเวอร์ Ubuntu 14.04.03 LTS


ฉันจะหลีกเลี่ยงการขยายตัวสัญลักษณ์ (เช่น * .gz) ในเส้นทาง cron อาจตีความเป็น * .gz ไม่ขยายไฟล์ gz ทั้งหมด
Archemar

คุณจะได้รับผลลัพธ์อะไรถ้าคุณทำงานโดยไม่มีการกระทำ/usr/bin/find /home/bkp/dbdump/*.gz -mtime +5
user9517

@Archemar เหตุใดสัญลักษณ์แทนจึงไม่ขยาย cronคำสั่งถูกเรียกใช้ผ่านเชลล์และเชลล์ขยาย wildcard
Barmar

cronควรส่งอีเมลพร้อมเอาต์พุตและข้อความแสดงข้อผิดพลาด คุณได้รับอีเมลดังกล่าวจากงานนี้หรือไม่?
Barmar

@ ฉันทำงานได้ตามที่คาดไว้
TommyPeanuts

คำตอบ:


6

ปัญหาคือcrontabไม่ได้$PATHตั้งค่าเมื่อมันทำงาน คุณสามารถระบุเส้นทางด้วยการเพิ่มลงในไฟล์ด้านบนที่เปิดผ่านcrontab -e:

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

(หรือสิ่งที่PATHคุณต้องการใช้) ซึ่งหมายความว่าคุณสามารถหลีกเลี่ยงการระบุพา ธ เต็มไปยังคำสั่งได้โดยตรงจาก cron

มีปัญหาหลายอย่างกับคำสั่งดั้งเดิมของคุณ findคุณพื้นถามเปลือกจะทำการขยายตัวสัญลักษณ์แทนมากกว่า ประการที่สองคุณไม่ได้ให้เส้นทางแบบเต็มสำหรับrm; ใช้/bin/rmหรือ/usr/bin/rmไม่ว่าจะอยู่ที่ไหนในระบบของคุณ (ดูwhich rm)

อาร์กิวเมนต์แรกสำหรับการค้นหาคือ "สถานที่ตั้งเพื่อค้นหา" และจากนั้นคุณระบุ "คำค้นหา" กับต่างๆ-<option>s ดังนั้นรูปแบบที่เหมาะสมของคำสั่งที่คุณต้องการเรียกใช้คือ:

find "/home/bkp/dbdump" -name "*.gz" -mtime +5 -exec rm -f {} \;

หรือ

find "/home/bkp/dbdump" -name "*.gz" -mtime +5 delete

หากคุณไม่ได้ระบุPATHคำนิยามข้างต้นให้ใช้:

/usr/bin/find "/home/bkp/dbdump" -name "*.gz" -mtime +5 -exec /bin/rm -f {} \;

หรือ

/usr/bin/find "/home/bkp/dbdump" -name "*.gz" -mtime +5 delete

1
มันควรจะมีการ$PATHตั้งค่า แต่มันจะเป็นค่าเริ่มต้นของระบบ สิ่งนี้จะรวมถึง/usr/binและ/binดังนั้นจึงควรสามารถค้นหาrmคำสั่งได้
Barmar

ดังนั้นฉันจึงลองใส่ $ PATH ใน crontab (แม้ว่าจะมีการกล่าวถึงที่อื่นมันอาจเป็นค่าเริ่มต้นไปยังเส้นทางของระบบหากไม่ได้ระบุไว้) และทำให้แน่ใจว่าทุกอย่างมีเส้นทางเต็ม ฉันยังใช้ -name "* .gz" แทน wildcard บน find path แต่ไม่มีอะไรเกิดขึ้น ดูเหมือนว่าคำสั่งจะไม่ทำงานและไม่มีข้อผิดพลาดเกิดขึ้น
TommyPeanuts

3

ลองใช้วิธีนี้แทน

find /home/bkp/dbdump -type f -name '*.gz' -mtime +5 -delete

เหตุใดคุณจึงเปลี่ยนเส้นทาง stderr ไปยังไฟล์ โดยค่าเริ่มต้นมันจะถูกส่งทางอีเมลหากมีการส่งออกใด ๆ
kasperd

ใช่มันเป็นความจริงที่โดยค่าเริ่มต้นคือการส่งอีเมลใด ๆ ไปยังสปูล MAIL ของผู้ใช้และสามารถอ่านได้โดยใช้จดหมาย
shad0VV

1
-maxdepth 1ที่จะได้รับผลเช่นเดียวกับคำสั่งเดิมที่คุณจะต้องเพิ่ม
Niels Keurentjes

0

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

สคริปต์ที่เป็นปัญหาใช้ csh ฉันเชื่อว่าสภาพแวดล้อม cron ของรูทบน Ubuntu จะใช้ / bin / bash (หรือ / bin / dash?) บางทีสิ่งนี้อาจขัดแย้งกับวิธีที่คำสั่ง find รันอยู่

ไม่ว่าจะด้วยวิธีใดปัญหาหลักที่แก้ไขได้แม้ว่าจะค่อนข้างไม่เหมาะสมก็ตาม

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