คุณจำเป็นต้องใส่เครื่องหมายคำพูดล้อมรอบตัวแปรในบริบทรายการทั้งหมดนั่นคือทุกหนทุกแห่งที่ตัวแปรอาจถูกขยายเป็นหลายค่าเว้นแต่ว่าคุณต้องการให้ผลข้างเคียงทั้ง 3 ของการทิ้งตัวแปรไว้โดยไม่มีเงื่อนไข
บริบทรายการรวมถึงการขัดแย้งกับคำสั่งง่าย ๆ เช่น[
หรือecho
, การfor i in <here>
กำหนดให้กับอาร์เรย์ ... มีบริบทอื่น ๆ ที่ตัวแปรยังจำเป็นต้องยกมา ที่ดีที่สุดคือการอ้างอิงตัวแปรเสมอถ้าคุณไม่มีเหตุผลที่ดี
คิดว่ากรณีที่ไม่มีคำพูด (ในบริบทรายการ) ในขณะที่แยก + globผู้ประกอบการ
ราวกับว่าเป็นecho $test
echo 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
เว้นวรรคและการขึ้นบรรทัดใหม่จะถูกปล้น