ถ้า, elif, else มีคำสั่งใน Bash


358

ฉันไม่สามารถดูเหมือนจะทำงานออกว่าปัญหาที่มีดังต่อไปนี้ifคำสั่งในการไปถึงและelif thenโปรดทราบว่าprintfยังคงอยู่ในระหว่างการพัฒนาฉันไม่สามารถทดสอบได้ในแถลงการณ์

ข้อผิดพลาดที่ฉันได้รับคือ:

./timezone_string.sh: line 14: syntax error near unexpected token `then'
./timezone_string.sh: line 14: `then'

และคำสั่งเป็นเช่นนั้น

if [ "$seconds" -eq 0 ];then
   $timezone_string="Z"
elif[ "$seconds" -gt 0 ]
then
   $timezone_string=`printf "%02d:%02d" $seconds/3600 ($seconds/60)%60`
else
   echo "Unknown parameter"
fi

7
ผมสงสัยว่าทำไมเราต้องthenคำสั่งในifและelifแต่ไม่ได้อยู่ในelseและยังอยู่ในทั่วไป

@ w17t เนื่องจากเราต้องการแยกเงื่อนไขออกจากลำดับ
Sasha

3
@codeforester ฉันไม่เห็นตรรกะมากนักในการทำเครื่องหมายคำถามการดู 500K เป็นคำถามซ้ำกับคำถามที่มีเพียง 5K
fedorqui 'ดังนั้นหยุดทำอันตราย'

การใช้เครื่องมือการจัดรูปแบบอัตโนมัติบางโค้ดอาจช่วยคุณได้โดยการเพิ่ม / ลบช่องว่างรอบ ๆ วงเล็บ คุณสามารถค้นหาปลั๊กอินสำหรับโปรแกรมแก้ไขของคุณ
Nj Subedi

คำตอบ:


453

มีช่องว่างระหว่างelifและถึง[:

elif[ "$seconds" -gt 0 ]

ควรจะเป็น

elif [ "$seconds" -gt 0 ]

เมื่อฉันเห็นคำถามนี้ได้รับมุมมองจำนวนมากสิ่งสำคัญคือต้องระบุว่าไวยากรณ์ที่ต้องติดตามคือ:

if [ conditions ]
# ^ ^          ^

หมายความว่าพื้นที่ที่มีความจำเป็นรอบวงเล็บ มิฉะนั้นจะไม่ทำงาน นี่เป็นเพราะ[ตัวมันเองเป็นคำสั่ง

เหตุผลที่ว่าทำไมคุณไม่เห็นสิ่งที่ชอบelif[: command not found(หรือคล้ายกัน) คือว่าหลังจากที่ได้เห็นifและthenเปลือกที่กำลังมองหาอย่างใดอย่างหนึ่งelif, หรือelse fiอย่างไรก็ตามพบอีกthen(หลังจากการจัดรูปแบบผิดelif[) เฉพาะหลังจากที่มีการแยกวิเคราะห์คำสั่งก็จะถูกดำเนินการ (และข้อผิดพลาดเหมือนelif[: command not foundจะเป็นเอาท์พุท)


33
เหตุผลที่วงเล็บต้องมีช่องว่างเพราะมันเป็นเพียงทางลัดสำหรับโปรแกรมจริง (อย่างน้อยวงเล็บแรกอันที่สองคือน้ำตาล syntactic ที่ฉันเข้าใจ) เพื่อให้เข้าใจมันดู manpage ที่แท้จริงสำหรับวงเล็บซ้าย:$ man [
Michael Johansen

3
โพสต์นี้ไม่ควรถูกปิดเหมือนการพิมพ์ผิดหรือไม่?
zx8754

3
@ zx8754 อาจเป็นไปได้ แต่ไม่ใช่ว่าจะเป็นวิธีที่ยอมรับได้ในการแก้ไขข้อผิดพลาดนี้ซึ่งดูมีประโยชน์มาก (มุมมอง 360K และการนับ)
fedorqui 'ดังนั้นหยุดการทำร้าย'

3
เพื่อนร่วมงานของฉันบางคนไม่เข้าใจแนวคิดของ "ช่องว่าง" หรือ "รูปแบบการเข้ารหัส" ดังนั้นนี่อาจไม่ใช่การพิมพ์ผิด
juzzlin

3
[เป็นชนิดของนามแฝงสำหรับคำสั่งทดสอบ นี่คือสาเหตุที่ต้องการอักขระว่าง เทียบเท่ากับif test "$seconds" -eq 0; then ... fi if [ "$seconds" -eq 0 ];then ... fi ]@LeiYang man testคือสิ่งที่คุณกำลังมองหา
Melicerte

303

คุณมีปัญหาเกี่ยวกับไวยากรณ์กับสคริปต์ของคุณ นี่คือรุ่นที่แก้ไขแล้ว:

#!/bin/bash

if [ "$seconds" -eq 0 ]; then
   timezone_string="Z"
elif [ "$seconds" -gt 0 ]; then
   timezone_string=$(printf "%02d:%02d" $((seconds/3600)) $(((seconds / 60) % 60)))
else
   echo "Unknown parameter"
fi

76
ผิดปกติพอนี้เป็นเพียง"if-then-else" โครงสร้างที่สมบูรณ์และเรียบง่ายที่ bashฉันพบได้ง่ายบน stackexchange ... ขอบคุณ
สัญลักษณ์แทน

1
การเยื้องเป็นทางเลือก ล่ามสามารถ (และควร) #!/bin/shเป็น

3
@ Chinggis6 เรื่องไร้สาระโดยรวมล่ามอาจเป็นได้#!/bin/shแต่ไม่จำเป็นต้องทำ
Camusensei

4
@Camusensei มันไม่ใช่เรื่องไร้สาระทั้งหมดที่shสามารถนำมาใช้แทนความเข้ากันได้ที่สูงขึ้น (ไม่ใช่ทุก * distros nix มีทุบตีเป็นเปลือกเริ่มต้น (บางคนมี ksh หรือเถ้า แต่ส่วนใหญ่จะขึ้นอยู่กับมาตรฐานshการทำงาน) นอกจากนี้ถ้าเฉพาะทุบตี หรือคุณสมบัติขั้นสูงไม่ได้ถูกใช้ในสคริปต์ดังนั้น 'sh' จึงควรใช้เป็นล่าม (อีกเหตุผลหนึ่ง) เพราะมันสามารถจัดการสคริปต์ได้ด้วยตัวเอง

6
@ Chinggis6 จริงเลือกคำที่ไม่ดีอยู่ข้างฉัน
Camusensei

25

[เป็นคำสั่ง (หรือ builtin ในบางเชลล์) มันจะต้องคั่นด้วยช่องว่างจากคำสั่งก่อนหน้า:

elif [

3
มันถูกแทนที่โดย builtin ใน bash แต่ข้อความของคุณยังคงถูกต้อง ใช้type -a [เพื่อดูว่า
Camusensei

มันก็เป็นเลขฐานสองที่มันแปลกสำหรับฉันเสมอ
mr.zog

4

ฉันอยากจะแนะนำให้คุณดูพื้นฐานของการปรับอากาศในทุบตี

สัญลักษณ์"["เป็นคำสั่งและต้องมีช่องว่างก่อนหน้า หากคุณไม่ให้ช่องว่างหลังจาก elif ของคุณระบบจะตีความelif [ตามคำสั่งเฉพาะซึ่งไม่ใช่สิ่งที่คุณต้องการในเวลานี้

การใช้งาน:

elif(A COMPULSORY WHITESPACE WITHOUT PARENTHESIS)[(A WHITE SPACE WITHOUT PARENTHESIS)conditions(A WHITESPACE WITHOUT PARENTHESIS)]

กล่าวโดยสรุปแก้ไขส่วนรหัสของคุณเป็น:

elif [ "$seconds" -gt 0 ]

คุณสามารถทำได้ดีโดยไม่มีข้อผิดพลาดในการรวบรวม ส่วนรหัสสุดท้ายของคุณควรมีลักษณะดังนี้:

#!/bin/sh    
if [ "$seconds" -eq 0 ];then
       $timezone_string="Z"
    elif [ "$seconds" -gt 0 ]
    then
       $timezone_string=`printf "%02d:%02d" $seconds/3600 ($seconds/60)%60`
    else
       echo "Unknown parameter"
    fi

2

ไม่มีช่องว่างระหว่างelifและ[ส่วนที่เหลือโปรแกรมของคุณถูกต้อง คุณต้องแก้ไขให้ถูกต้องตรวจสอบ นี่คือโปรแกรมคงที่:

#!/bin/bash

if [ "$seconds" -eq 0 ]; then
   timezone_string="Z"
elif [ "$seconds" -gt 0 ]; then
   timezone_string=$(printf "%02d:%02d" $((seconds/3600)) $(((seconds / 60) % 60)))
else
   echo "Unknown parameter"
fi

ลิงค์ที่มีประโยชน์ที่เกี่ยวข้องกับbashนี้ถ้ามีคำสั่ง else

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