เมื่อคุณเรียกใช้คำสั่งนี้:
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