มีวิธีใดบ้างที่ฉันจะบอก cron ให้เรียกใช้แอป แต่ไม่เรียกใช้ถ้ามีกระบวนการอยู่แล้ว?
มีวิธีใดบ้างที่ฉันจะบอก cron ให้เรียกใช้แอป แต่ไม่เรียกใช้ถ้ามีกระบวนการอยู่แล้ว?
คำตอบ:
วิธีที่ง่ายที่สุดใช้ pgrep
ใน crontab:
* * * * * pgrep processname > /dev/null || /path/to/processname -args0 -args1
export DISPLAY=:0
เพื่อป้องกันCould not connect to display
ข้อผิดพลาด * * * * * export DISPLAY=:0 && pgrep processname > /dev/null || /path/to/processname -args0 -args1
เรียกใช้สคริปต์แทนโปรแกรมโดยตรง มีความเป็นไปได้มากมาย ตัวอย่างเช่น :
MYPROG="myprog"
RESTART="myprog params"
PGREP="/usr/bin/pgrep"
# find myprog pid
$PGREP ${MYPROG}
# if not running
if [ $? -ne 0 ]
then
$RESTART
fi
pgrep myprog; if [ $? -ne 0 ]; then ...
จะเขียนได้ดีกว่าเป็นif ! pgrep myprog; then ...
$?
ตัวอย่างเช่นโดยเพิ่มข้อความบันทึกหรือการจัดการข้อผิดพลาดระหว่างบรรทัด
สคริปต์นี้จะไม่ทำงานอีกครั้งหากอินสแตนซ์ก่อนหน้านี้ยังไม่เสร็จสิ้น หากคุณต้องการที่จะไม่เรียกใช้บางอย่างหากกระบวนการเฉพาะอื่นกำลังทำงานอยู่ให้ดูสคริปต์ของ harrymc
DATE=`date +%c`;
ME=`basename "$0"`;
LCK="./${ME}.LCK";
exec 8>$LCK;
if flock -n -x 8; then
echo ""
echo "Starting your script..."
echo ""
[PUT YOUR STUFF HERE]
echo ""
echo "Script started $DATE";
echo "Script finished `date +%c`";
else
echo "Script NOT started - previous one still running at $DATE";
fi
คุณสามารถใช้แฟ้มล็อคในสคริปต์ของคุณ แต่โปรดดูการจัดการกระบวนการ
flock
เป็นหนึ่งยูทิลิตี้ที่สามารถใช้
*/5 * * * * root flock /run/shm rsync -auhx --numeric-ids -e "ssh -T -c arcfour128 -o Compression=no -x" [source] [user]@[host]:[dest]
cron
นี้มักจะถูกจัดการโดยโปรแกรมตัวเองมากกว่าโดย มีสองมาตรฐานเทคนิคนี้:
1) grep
ผลลัพธ์ของps
เพื่อดูว่ามีกระบวนการที่ใช้ชื่อนั้นทำงานอยู่หรือไม่
2) เมื่อเริ่มต้นให้ตรวจสอบการมีอยู่ของไฟล์ pid (รหัสกระบวนการ) โดยปกติที่/var/run/program_name.pid
และถ้ามีอยู่ให้อ่าน pid จากไฟล์และตรวจสอบว่ากระบวนการนั้นยังคงมีอยู่หรือไม่ ถ้าเป็นเช่นนั้นปฏิเสธที่จะเริ่ม หากไฟล์ pid ไม่มีอยู่หรือ pid ในไฟล์หายไปจากนั้นสร้างไฟล์ pid เขียน id กระบวนการของคุณลงในนั้นและดำเนินการต่อด้วยการเริ่มต้นปกติ
ในขณะที่เป็นไปได้ในทางเทคนิคในการเขียนทุบตีท่อที่จะทำสิ่งเหล่านี้โดยตรงใน crontab ของคุณมันจะดีกว่าที่จะเพิ่มไปยังโปรแกรมที่กำลังเริ่มต้น (เพื่อที่พวกเขาจะนำไปใช้ จัดการสิ่งนี้ตามที่ harrymc แนะนำ
* * * * * pgrep -f "[p]attern" > /dev/null || /path/to/processname -args0 -args1
ฉันได้นำคำตอบกลับมาใช้ซ้ำพร้อมกับปรับปรุงการจับคู่รูปแบบ pgrep โดยไม่มีตัวเลือก f ไม่ตรงกับรูปแบบกระบวนการ ยังมีปัญหากับการใช้ตัวเลือก f ด้วยตัวเลือก f เปลือกหอยที่วางไข่ cron จะถูกจับคู่เสมอและส่งคืน pid ดังนั้นกระบวนการจะไม่รีสตาร์ท
การเพิ่ม [] รอบรูปแบบตัวอักษรตัวหนึ่งตรงกับกระบวนการเท่านั้นและ pid ของเปลือก cron จะไม่ถูกส่งกลับ
เอกสาร: https://www.timkay.com/solo/
solo เป็นสคริปต์ที่ง่ายมาก (10 บรรทัด) ที่ป้องกันไม่ให้โปรแกรมทำงานมากกว่าหนึ่งสำเนาในเวลาเดียวกัน มันมีประโยชน์กับ cron เพื่อให้แน่ใจว่างานไม่ทำงานก่อนที่งานก่อนหน้าจะเสร็จสิ้น
ตัวอย่าง
* * * * * solo -port=3801 ./job.pl blah blah