ปัญหากับ $ RANDOM ใน crontab


9

ฉันมีปัญหาแปลก ๆ กับ $ RANDOM เป็น cron ฉันต้องการรันคำสั่งโดยการสุ่มจำนวนนาทีหลังจาก cronjob fires

ตัวอย่างนี้ทำงานได้โดยตรงในเทอร์มินัลและชะลอคำสั่งสูงสุด 30 วินาที (แทนที่คำสั่งด้วยสิ่งที่คุณต้องการจริง ๆ แล้วมันคือ echo to / dev / ttyUSB0):

sleep `expr $RANDOM \% 30` ; command

หากวางบรรทัดเดียวกันใน crontab คำสั่งจะยิงทันทีโดยไม่ล่าช้า:

* * * * * sleep `expr $RANDOM \% 30` ; command

หากฉันใช้นิพจน์ที่ไม่มี $ RANDOM จะใช้งานได้ดี - สิ่งนี้จะล่าช้า 15 วินาที:

* * * * * sleep `expr 10 + 5` ; command

กล่าวอีกนัยหนึ่งดูเหมือนว่า $ RANDOM จะไม่ทำงานใน cron

แต่ไม่ใช่เพียงเพราะ $ RANDOM เองประเมินเป็นศูนย์เพราะสิ่งนี้จะทำให้เกิดความล่าช้า 10:

* * * * * sleep `expr $RANDOM \% 30 + 10` ; command

ฉันลองใช้ด้วย && จากที่มีอยู่ แต่นั่นก็ไม่ได้ช่วยอะไร ในความเป็นจริงแล้วคำสั่งจะไม่ยิงเลย!

แน่นอนฉันสามารถวางความล่าช้าในสคริปต์ซึ่งเรียกจาก crontab แล้ว แต่นั่นไม่ได้อธิบายปัญหาของฉันและไม่ทำให้ฉันเรียนรู้ :-)

มันคือ Debian Lenny ถ้ามันสร้างความแตกต่าง

คำตอบ:


18

cronใช้/bin/shเปลือกเพื่อดำเนินการงาน ใน distros บางนี้เป็น symlink dashไป ไม่สนับสนุน$RANDOMตัวแปรซึ่งเป็นbashส่วนขยาย -specific

  • ด้วย vixie-cron คุณสามารถวางสายSHELL=/bin/bashที่ด้านบนของ crontab ของคุณ

  • มิฉะนั้นคุณจะต้องชำระด้วยหรือbash -c 'echo $RANDOM'perl -e 'print int(rand(65535))'

    (ในตัวอย่างข้างต้น 65535 เป็นจำนวนสูงสุดที่จะส่งคืนคุณสามารถใช้คณิตศาสตร์อื่น ๆ ภายในสคริปต์ได้เช่นกัน)

  • ในระบบที่กำหนดค่าอย่างเหมาะสมคุณจะได้รับแจ้งเกี่ยวกับสิ่งนี้ด้วยcronตัวเอง - มันจะส่งงานออกมาเสมอรวมถึงข้อความแสดงข้อผิดพลาดทางอีเมล ติดตั้ง MTA น้ำหนักเบา


นอกจากนี้ในทุบตีเป็นที่ต้องการมากกว่า$(( ))`expr`


ครั้งสุดท้ายที่ฉันตรวจสอบ/bin/shไม่ได้เป็นเปลือกจริงเพียง symlink ไปยังเปลือกที่ต้องการของดูแลระบบ (ปกติทุบตีหรือเส้นประ) ใน Debian
Hello71

1
@ Hello71: ซึ่งเป็นสิ่งที่ฉันพูดในโพสต์ อย่างไรก็ตามมันเป็นเรื่องธรรมดาสำหรับซอฟต์แวร์ระบบที่จะเรียกใช้/bin/sh(และคาดว่ามันจะเข้ากันได้กับ Bourne shell) ตัวอย่างคือsystem()ฟังก์ชั่นใน glibc ดังนั้น/bin/shมักจะชี้ไปที่เชลล์ที่เข้ากันได้กับ Bourne ที่เร็วที่สุด และดูแลระบบควรจะตั้งค่าการตั้งค่าของเขาในบรรทัดที่เหมาะสมของ / etc / passwd ไม่บังคับใช้ระบบการตั้งค่าที่กว้าง
1686

@ Hello71: ... โอเคส่วนใหญ่ที่ฉันพูดในโพสต์ (ฉันรู้ว่า distros อื่น ๆ ส่วนใหญ่เชื่อมโยงshไปถึงbashแต่ดูเหมือนจะไม่เกี่ยวข้องกัน)
user1686

คุณถูกต้อง/bin/shชี้ไปที่ประ จนถึงตอนนี้ฉันยังไม่เคยได้ยินเรื่องนี้เลย ฉันเงยหน้าขึ้นและมันเป็นตัวแปรที่เบามากของการทุบตี นอกจากนี้ฉันไม่ทราบว่า cron วิ่งในสภาพแวดล้อมที่ "พิการ" แต่มันอธิบายปัญหาอื่น ๆ อีกมากมายที่ฉันมีในอดีต Btw ฉันเริ่มใช้$(())แต่เนื่องจากมันใช้งานไม่ได้ฉันจึงลองใช้ทุกรูปแบบและจบลงด้วยexprซึ่งแน่นอนว่ามันไม่ได้ผลเช่นกัน แต่นั่นคือที่ฉันสิ้นสุด :-) เป็นไปได้ไหมที่จะใช้เชลล์ bash ปกติโดยไม่มีข้อ จำกัด ในการใช้bash -c 'xxxx'? Btw มันเป็นไปไม่ได้ไหมที่จะแสดงความคิดเห็น?
marlar

@marlar: 1) dashเป็นเชลล์ มันไม่ได้ปกติbashมากไปกว่านั้น มันไม่ใช่ตัวแปรของมันเช่นกัน 2) ดูคะแนน # 1 และ # 2 ในคำตอบ
user1686

2

cronโดยทั่วไปแล้วจะทำงานโดยมีสภาพแวดล้อม "เต็ม" น้อยลงซึ่งหมายความว่าคุณไม่มีตัวแปรสภาพแวดล้อมเดียวกันมากมายให้คุณใช้ เห็นได้ชัดว่า$RANDOMเป็นหนึ่งดังกล่าวและในความเป็นจริงของคุณsleepคำสั่งเป็นเพียงความล้มเหลวกับข้อผิดพลาดเนื่องจากของตัวแปรที่ไม่ได้กำหนด - ซึ่งเป็นเหตุผลที่คำสั่งของคุณล้มเหลวในการทำงานเลยเมื่อคุณเปลี่ยนไปแทน&& ;(อันที่จริงแล้ว$RANDOMเป็นฟังก์ชั่น Bash แต่cronไม่ได้ทำงานในสภาพแวดล้อม Bash แบบเต็มซึ่งเห็นได้ชัดว่าขาดฟังก์ชั่นนี้)

เพื่อให้งานนี้สำเร็จคุณจะต้องใช้สคริปต์ Bash แยกต่างหากดังที่คุณกล่าว หรือคุณอาจจะสามารถหาวิธีที่จะใช้cat /dev/urandomโดยตรงในcronคำสั่ง แต่มันอาจจะง่ายกว่าที่จะย้ายสิ่งที่คุณมีอยู่ไปยังสคริปต์ Bash ที่แยกต่างหาก


1
ไม่สวย แต่ฉันพบวิธีแก้ปัญหานี้ซึ่งสอดคล้องกับข้อเสนอแนะของคุณ: sleep $ (expr od -An -N1 -i /dev/urandom\% 30); คำสั่ง
marlar

1
$RANDOMไม่ได้เป็นส่วนหนึ่งของสภาพแวดล้อม "เต็ม" มันไม่เกี่ยวอะไรกับตัวแปรสภาพแวดล้อมที่ตั้งไว้ในกระบวนการเริ่มต้น มันเป็นตัวแปรพิเศษที่สร้าง "ในทันที" ในทุบตี ค่าใหม่จะถูกสร้างขึ้นเสมอเมื่อใดก็ตามที่อ่านตัวแปร --- cronโดยค่าเริ่มต้นจะใช้/bin/shในระบบที่/bin/shไม่ได้เชื่อมโยงกับbash $RANDOMจะไม่ทำงานโดยค่าเริ่มต้น
pabouk
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.