คำหลักเช่นif, then, else, fi, for, caseและอื่น ๆ ที่จำเป็นต้องอยู่ในสถานที่ที่คาดว่าเปลือกชื่อคำสั่งที่ มิฉะนั้นจะถือว่าเป็นคำทั่วไป ตัวอย่างเช่น,
echo if
เพียงพิมพ์ifมันไม่ได้เริ่มคำสั่งตามเงื่อนไข
ดังนั้นในสาย
if [ -r "$NAME" -af "$NAME" ] then
คำthenนั้นเป็นอาร์กิวเมนต์ของคำสั่ง[(ซึ่งมันจะบ่นเกี่ยวกับว่ามันจะต้องวิ่ง) เชลล์ทำการค้นหาthenและค้นหาfiตำแหน่งคำสั่ง in นับตั้งแต่มีการifที่ยังคงมองหาของthenที่fiไม่คาดคิดมีข้อผิดพลาดทางไวยากรณ์
คุณต้องใส่ตัวยกเลิกคำสั่งก่อนthenเพื่อให้เป็นที่รู้จักว่าเป็นคำหลัก ตัวยกเลิกคำสั่งที่ใช้กันทั่วไปส่วนใหญ่คือตัวแบ่งบรรทัด แต่ก่อนหน้าthenนี้เป็นเรื่องปกติที่จะใช้เครื่องหมายอัฒภาค (ซึ่งมีความหมายเหมือนกับตัวแบ่งบรรทัด)
if [ -r "$NAME" -af "$NAME" ]; then
หรือ
if [ -r "$NAME" -af "$NAME" ]
then
เมื่อคุณแก้ไขปัญหาที่คุณจะได้รับข้อผิดพลาดอื่นจากคำสั่งเพราะมันไม่เข้าใจ[ -afคุณน่าจะหมายถึง
if [ -r "$NAME" -a -f "$NAME" ]; then
แม้ว่าคำสั่งทดสอบจะมีลักษณะเป็นตัวเลือก แต่คุณไม่สามารถรวมกลุ่มสิ่งเหล่านี้ได้ พวกเขากำลังผู้ประกอบการของ[คำสั่งและพวกเขาต้องการให้แต่ละจะเป็นคำที่แยกต่างหาก (เช่นการทำ[และ])
อย่างไรก็ตามถึง[ -r "$NAME" -a -f "$NAME" ]อย่างไรฉันก็แนะนำให้เขียนเช่นกัน
[ -r "$NAME" ] && [ -f "$NAME" ]
หรือ
[[ -r $NAME && -f $NAME ]]
เป็นการดีที่สุดที่จะรักษา[ … ]เงื่อนไขให้ง่ายเนื่องจาก[คำสั่งไม่สามารถแยกความแตกต่างของโอเปอเรเตอร์ออกจากตัวถูกดำเนินการได้อย่างง่ายดาย หาก$NAMEดูเหมือนว่าโอเปอเรเตอร์และปรากฏในตำแหน่งที่โอเปอเรเตอร์ที่ถูกต้องอาจถูกวิเคราะห์คำเป็นโอเปอเรเตอร์ สิ่งนี้จะไม่เกิดขึ้นในกรณีง่าย ๆ ที่เห็นในคำตอบนี้ แต่กรณีที่ซับซ้อนกว่านั้นอาจมีความเสี่ยง การเขียนสิ่งนี้ด้วยการเรียกไปยัง[และใช้ตัวดำเนินการเชิงตรรกะของเชลล์แยกกันเพื่อหลีกเลี่ยงปัญหานี้
ไวยากรณ์ที่สองใช้โครงสร้างแบบมี[[ … ]]เงื่อนไขซึ่งมีอยู่ใน bash (และ ksh และ zsh แต่ไม่ใช่ sh แบบธรรมดา) โครงสร้างนี้ถูกไวยากรณ์พิเศษในขณะที่[จะแยกกันเช่นคำสั่งอื่นใดที่ทำให้คุณสามารถใช้สิ่งที่ต้องการ&&ทั้งภายในและคุณไม่จำเป็นต้องอ้างตัวแปรยกเว้นในข้อโต้แย้งกับผู้ประกอบการบางสตริง ( =, ==, !=, =~) (ดูเมื่อสองครั้ง quoting จำเป็น ?สำหรับรายละเอียด)