คุณจำเป็นต้องใส่เครื่องหมายคำพูดล้อมรอบตัวแปรในบริบทรายการทั้งหมดนั่นคือทุกหนทุกแห่งที่ตัวแปรอาจถูกขยายเป็นหลายค่าเว้นแต่ว่าคุณต้องการให้ผลข้างเคียงทั้ง 3 ของการทิ้งตัวแปรไว้โดยไม่มีเงื่อนไข
บริบทรายการรวมถึงการขัดแย้งกับคำสั่งง่าย ๆ เช่น[หรือecho, การfor i in <here>กำหนดให้กับอาร์เรย์ ... มีบริบทอื่น ๆ ที่ตัวแปรยังจำเป็นต้องยกมา ที่ดีที่สุดคือการอ้างอิงตัวแปรเสมอถ้าคุณไม่มีเหตุผลที่ดี
คิดว่ากรณีที่ไม่มีคำพูด (ในบริบทรายการ) ในขณะที่แยก + globผู้ประกอบการ
ราวกับว่าเป็นecho $testecho glob(split("$test"))
พฤติกรรมของเชลล์ทำให้คนส่วนใหญ่สับสนเพราะในภาษาอื่น ๆ ส่วนใหญ่คุณใส่เครื่องหมายคำพูดรอบสตริงคงที่เช่นputs("foo")และไม่ใช่ตัวแปร (เช่นputs(var)) ในขณะที่เชลล์เป็นอีกวิธีหนึ่ง: ทุกอย่างเป็นสตริงในเชลล์ดังนั้นการใส่เครื่องหมายคำพูดรอบ ๆ ทุกสิ่ง จะยุ่งยากคุณคุณไม่จำเป็นต้องecho test "echo" "test"ในเปลือกคำพูดจะใช้สำหรับสิ่งอื่น: ป้องกันความหมายพิเศษบางอย่างของตัวละครบางตัวและ / หรือส่งผลกระทบต่อพฤติกรรมของการขยายตัวบางอย่าง
ใน[ -n $test ]หรือecho $testเชลล์จะแบ่ง$test(ตามค่าเริ่มต้น) แล้วดำเนินการสร้างชื่อไฟล์ (ขยาย*รูปแบบทั้งหมด'?' ... ไปยังรายการไฟล์ที่ตรงกัน) แล้วส่งรายการอาร์กิวเมนต์ไปยัง[หรือechoคำสั่ง .
"[" "-n" glob(split("$test")) "]"อีกครั้งคิดว่ามันเป็น ถ้า$testว่างเปล่าหรือมีเพียงช่องว่าง (spc, tab, nl) ดังนั้นโอเปอเรเตอร์แยก + glob จะส่งคืนรายการว่างดังนั้นค่า[ -n $test ]จะเป็น"[" "-n" "]"ซึ่งเป็นการทดสอบเพื่อตรวจสอบว่า "-n" เป็นสตริงว่างหรือไม่ แต่ลองจินตนาการว่าจะเกิดอะไรขึ้นถ้า$testเป็น "*" หรือ "= foo" ...
ใน[ -n "$test" ], [ถูกส่งผ่านไปสี่ข้อโต้แย้ง"[", "-n", ""และ"]"(ไม่ทราบราคา) ซึ่งเป็นสิ่งที่เราต้องการ
ไม่ว่าจะเป็นechoหรือ[สร้างความแตกต่างไม่เพียง แต่มันจะechoส่งออกสิ่งเดียวกันไม่ว่าจะผ่านการโต้แย้งว่างเปล่าหรือไม่มีการโต้แย้งเลย
ดูเพิ่มเติมที่คำตอบสำหรับคำถามที่คล้ายกันนี้สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับ[คำสั่งและ[[...]]โครงสร้าง
echoเว้นวรรคและการขึ้นบรรทัดใหม่จะถูกปล้น