ฉันจะใช้คำสั่ง If-Else ตามวันในสัปดาห์ได้อย่างไร


10

ปัญหา: ฉันต้องตรวจสอบว่าวันนี้เป็นวันพฤหัสบดีหรือไม่และดำเนินการต่าง ๆ ตามผลลัพธ์ของเงื่อนไขนี้ ฉันลองวิธีที่แตกต่างกันสองวิธี:

ได้รับชื่อวัน:

DAYOFWEEK=$(date +"%a")
echo DAYOFWEEK: $DAYOFWEEK
if ["$DAYOFWEEK" == "Thu"]; 
then   
   echo YES
else
    echo NO
fi

รับวัน NUM:

DAYOFWEEK=$(date +"%u")
echo DAYOFWEEK: $DAYOFWEEK

if ["$DAYOFWEEK" == 4]; 
then
   echo YES
else
   echo NO
fi

ในทั้งสองกรณีผลลัพธ์คือ NO แม้ว่ามันควรจะเป็นใช่ เกิดอะไรขึ้น?


1
สังเกตด้าน: ผู้ที่;จะต้องถ้าคุณจะต้องอยู่ในแนวเดียวกับthen ifในกรณีนี้พวกเขาซ้ำซ้อน
จัดการ

คำตอบ:


12

ปัญหาคือช่องว่างที่ขาดหายไป

รหัสต่อไปนี้จะทำงานในเชลล์ที่[คำสั่ง builtin ยอมรับ==เป็นนามแฝงสำหรับ=:

if [ "$DAYOFWEEK" == 4 ];  then    echo YES; else    echo NO; fi

แต่โปรดจำไว้ (ดูhelp testในbash):

  • ==ไม่ได้กล่าวถึงอย่างเป็นทางการคุณควรใช้=สำหรับการเปรียบเทียบสตริง
  • -eqมีไว้สำหรับการทดสอบเลขคณิตทศนิยม (จะไม่สร้างความแตกต่างที่นี่date +%uแต่จะdate +%dเป็นเช่นเมื่อมันมาถึงการเปรียบเทียบ04และ4ที่เป็นตัวเลขเดียวกัน แต่แตกต่างกันเล็กน้อย)

ฉันต้องการ:

 if [ "${DAYOFWEEK}" -eq 4 ];  then    echo YES; else    echo NO; fi

โดยทั่วไปคุณควรจะต้องการวันจำนวนวิธีการเพราะมีการพึ่งพาน้อยในปัจจุบันสถานที่เกิดเหตุ ในระบบของฉันการส่งออกของวันนี้คือdate +"%a"Do


3

อย่ามองข้ามcaseซึ่งมักเป็นวิธีที่ดีกว่าในการทำสิ่งนี้:

นอกจากนี้ระวังว่าผลลัพธ์ของdate +%aการขึ้นอยู่กับสถานที่ดังนั้นถ้าคุณคาดว่าชื่อภาษาอังกฤษสคริปต์ของคุณจะหยุดทำงานเมื่อมีการเรียกใช้โดยผู้ใช้ฝรั่งเศสหรือเกาหลีเช่น

case $(LC_ALL=C date +%a) in
   (Mon) echo first day of the week;;
   (Thu) do-something;;
   (Sat|Sun) echo week-end;;
   (*) echo any other day;; # last ;; not necessary but doesn't harm
esac

โปรดทราบว่าข้างต้นเป็นหนึ่งในกรณีที่หายากซึ่ง $(...)ไม่จำเป็นต้องยกมา (แม้ว่าคำพูดจะไม่เป็นอันตรายเหมือนในvar="$(...)")


0

ในความคิดเดียวกันฉันใช้โค้ดต่อไปนี้เพื่อ "ปิด" cron ก่อนเวลาที่เลือก
แน่นอนฉันต้องการแก้ไข crontab เอง ... ถ้าฉันได้รับสิทธิ์ที่จำเป็นในการ :)

นี่คือการทดสอบง่ายๆที่ยกเลิกสคริปต์ทุบตีเว้นแต่ว่าเราอยู่ตอนกลางคืน

# Delay or restrict execution.
# Here, we quit unless hour is greater than (gt) 2 and (-a) lower than (lt) 7
# i.e. execution happens only at 3,4,5&6 o'clock.
if  /usr/bin/test `date '+%H'` -gt 2 -a `date '+%H'` -lt 7; then
  echo LETS_START_PROCESSING;
else
  exit;
fi

#Put job here

ทำไมต้องใช้/usr/bin/testแทน[คำสั่งbuiltin ของเชลล์?
Stéphane Chazelas

@ Stéphane Chazelas ฉันไม่ได้ใช้ 3,4,5,6 เพราะฉันไม่มีสิทธิ์เข้าถึง crontab ( นี่คือบรรทัดที่ 2 ของโพสต์ของฉัน :) เซิร์ฟเวอร์ของเราได้รับการจัดการโดย Claranet และเราได้สูญเสียตั๋วไปหนึ่งสัปดาห์เพื่อรับ ... cron ที่ใช้งานได้ (ไม่ใช่ล้อเล่น) ดังนั้นเราจึงหลีกเลี่ยงการทำให้ยุ่งเหยิงและเปิดตั๋วใหม่เมื่อเราทำได้ :) ด้วยเหตุนี้เราจึงขอให้ทำงาน cron รายชั่วโมงแทนที่จะเป็นรายวันและจนกว่าการทดสอบทั้งหมดของเราจะเสร็จสิ้นมันจะง่ายกว่าที่จะไม่สัมผัสงานและ เพิ่มการควบคุมของเราในสคริปต์ที่เรียกใช้งาน
Balmipour

อ่าขอโทษด้วยฉันคิดว่าคุณหมายความว่าคุณไม่มีสิทธิ์ในการแก้ไขcronไฟล์ที่เรียกทำงานได้ซึ่งต่างจาก crontab ของผู้ใช้
Stéphane Chazelas

@ Stéphane Chazelas เกี่ยวกับไวยากรณ์ทดสอบฉันชอบมากกว่า [] หรือ [[]] เพราะฉันลองใช้สคริปต์ของฉันบนเซิร์ฟเวอร์อื่น ๆ ก่อนซึ่งฉันสามารถใช้ crontab ได้ หลังจากเซอร์ไพรส์กับ crons มากเกินไปฉันก็มีนิสัยที่จะใช้เส้นทางที่แน่นอนใน crontabs ให้มากที่สุด บางคนอาจบอกว่ามันทำให้การทดสอบน่าเกลียดและจะถูกต้อง ... แต่ฉันจะตอบว่าการทดสอบเชลล์นั้นน่าเกลียดอยู่เสมอและจะถูกด้วย ^^ สิ่งที่สำคัญสำหรับฉันคือการมีคำตอบซึ่งจะทำงานร่วมกับ คัดลอก / วางอย่างง่ายและรวมถึงการอธิบายบางอย่าง
Balmipour

1
โปรดทราบว่าจะเลิกใน-a testตามปกติคุณจะใช้: hour=$(date +%H); if [ "$hour" -gt 2 ] && [ "$hour" -lt 7 ](หรือhour=`date +%H`ถ้าคุณจำเป็นต้องเข้ากันได้กับเชลล์ Bourne นั่นคือ Solaris 10 และเก่ากว่าและอาจเป็นบาง SCO unices ที่หายากในปัจจุบัน)
Stéphane Chazelas

0

หากต้องการหยุดสคริปต์ในวันของสัปดาห์เพียงลบบรรทัดของวัน:

DAYOFWEEK=$(date +"%u")
echo "$DAYOFWEEK";
if [ "$DAYOFWEEK" == 1 ]; then exit; else echo; fi
if [ "$DAYOFWEEK" == 2 ]; then exit; else echo; fi
if [ "$DAYOFWEEK" == 3 ]; then exit; else echo; fi
if [ "$DAYOFWEEK" == 4 ]; then exit; else echo; fi
if [ "$DAYOFWEEK" == 5 ]; then exit; else echo; fi
if [ "$DAYOFWEEK" == 6 ]; then exit; else echo; fi
if [ "$DAYOFWEEK" == 7 ]; then exit; else echo; fi

ยินดีต้อนรับสู่ Unix SE! ฉันไม่แน่ใจว่าฉันเข้าใจบรรทัดแรกของคุณถูกต้องหรือไม่ จะif [ "$DAYOFWEEK" -lt 7 ]ดีกว่าไหม
peterh - Reinstate Monica

-1

ประการแรกคุณควรเสนอราคา DAYOFWEEK = "$ (date +% u)"

และคุณต้องมีช่องว่างในแต่ละด้านของเครื่องหมาย [และ]

เซมิโคลอนที่ส่วนท้ายของบรรทัดนั้นซ้ำซ้อน


1
ไม่จำเป็นต้องมีการอ้างอิง
H. -Dirk Schmitt

หากต้องการขยายความคิดเห็นของ @ H. -DirkSchmitt: สาเหตุที่ไม่จำเป็นต้องมีการอ้างถึงก็คือเอาต์พุตจะไม่มีช่องว่างใด ๆ
CVn

@ MichaelKjörling: ไม่ - ไม่จำเป็น ;-) ลองตัวอย่าง:a=$(echo 1 2 3); echo $a;
H. -Dirk Schmitt

@ H. -DirkSchmitt ที่a=$(echo "1 2 3"); echo $aมีช่องว่างหลายจุดระหว่างตัวเลข (StackExchange จะไม่ให้ฉันทำสำเนาและวางแบบง่าย ๆ น่าเสียดาย)
CVn

@ MichaelKjörling - ดู man bash "หากการทดแทนปรากฏภายในเครื่องหมายคำพูดคู่การแยกคำและการขยายชื่อพา ธ จะไม่ถูกดำเนินการกับผลลัพธ์" ดังนั้นในกรณีของคำถามและตัวอย่าง "1 2 3" ไม่มีความแตกต่าง
H. -Dirk Schmitt
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.