เมื่อคุณเรียกใช้คำสั่งนี้:
ls
lsแสดงขั้วการส่งออกของ
เมื่อคุณเรียกใช้คำสั่งนี้:
echo $(ls)
เชลล์จับเอาท์พุทของ$(ls)และทำการแยกคำบนมัน ด้วยค่าเริ่มต้นIFSซึ่งหมายความว่าลำดับทั้งหมดของพื้นที่สีขาวรวมถึงอักขระขึ้นบรรทัดใหม่จะถูกแทนที่ด้วยช่องว่างเดียว นั่นคือสาเหตุที่ผลลัพธ์ของการecho $(ls)ปรากฏบนหนึ่งบรรทัด
สำหรับการสนทนาขั้นสูงของการแยกคำเห็นของเกร็กคำถามที่พบบ่อย
ระงับการแยกคำ
เชลล์ไม่ดำเนินการแยกคำในสตริงในเครื่องหมายคำพูด ดังนั้นคุณสามารถระงับการแยกคำและเก็บเอาท์พุทหลายบรรทัดด้วย:
echo "$(ls)"
ls และหลายเอาท์พุท
คุณอาจสังเกตเห็นว่าlsบางครั้งพิมพ์มากกว่าหนึ่งไฟล์ต่อบรรทัด:
$ ls
file1 file2 file3 file4 file5 file6
นี่เป็นค่าดีฟอลต์เมื่อเอาต์พุตของlsไปยังเทอร์มินัล เมื่อเอาต์พุตไม่ไปยังเทอร์มินัลโดยตรงให้lsเปลี่ยนค่าดีฟอลต์เป็นหนึ่งไฟล์ต่อบรรทัด:
$ echo "$(ls)"
file1
file2
file3
file4
file5
file6
man lsลักษณะการทำงานนี้จะถูกบันทึกไว้ใน
ความละเอียดอื่น: การทดแทนคำสั่งและการขึ้นบรรทัดใหม่
$(...)เป็นคำสั่งเปลี่ยนตัวและลบเปลือกลากตัวอักษรขึ้นบรรทัดใหม่จากการส่งออกของแทนคำสั่ง โดยปกติจะไม่สามารถสังเกตเห็นได้เนื่องจากโดยปกติแล้วechoจะเพิ่มหนึ่งบรรทัดใหม่ต่อท้ายเอาต์พุต ดังนั้นหากคุณสูญเสียหนึ่งบรรทัดใหม่จากจุดสิ้นสุด$(...)และคุณได้รับบรรทัดใหม่echoจะไม่มีการเปลี่ยนแปลง อย่างไรก็ตามหากผลลัพธ์ของคำสั่งของคุณลงท้ายด้วยอักขระขึ้นบรรทัดใหม่2ตัวขึ้นไปในขณะที่echoเพิ่มกลับมาหนึ่งตัวเอาต์พุตของคุณจะหายไปหนึ่งบรรทัดขึ้นไป ตัวอย่างเช่นเราสามารถใช้printfเพื่อสร้างอักขระขึ้นบรรทัดใหม่ โปรดทราบว่าคำสั่งทั้งสองต่อไปนี้แม้จะมีจำนวนบรรทัดใหม่ต่างกันให้สร้างเอาต์พุตเดียวกันของบรรทัดว่างหนึ่งบรรทัด
$ echo "$(printf "\n")"
$ echo "$(printf "\n\n\n\n\n")"
$
man bashลักษณะการทำงานนี้จะถูกบันทึกไว้ใน
แปลกใจอีกประการหนึ่ง: การขยายชื่อพา ธ สองครั้ง
ลองสร้างสามไฟล์:
$ touch 'file?' file1 file2
สังเกตความแตกต่างระหว่างls file?และecho $(ls file?):
$ ls file?
file? file1 file2
$ echo $(ls file?)
file? file1 file2 file1 file2
ในกรณีของecho $(ls file?), glob ไฟล์file?จะขยายตัวเป็นครั้งที่สองทำให้ชื่อไฟล์file1และfile2ปรากฏให้เห็นเป็นครั้งที่สองในการส่งออก นี่เป็นเพราะตามที่ Jeffiekins ชี้ให้เห็นการขยายชื่อพา ธจะดำเนินการโดยเชลล์ก่อนที่จะlsถูกรันและจากนั้นอีกครั้งก่อนที่echoจะรัน
สามารถขยายชื่อพา ธที่สองได้หากเราใช้เครื่องหมายคำพูดคู่:
$ echo "$(ls file?)"
file?
file1
file2