คำตอบของ @Gilles นั้นยอดเยี่ยมจริง ๆ เขาอธิบาย (โดยละเอียด) ปัญหาที่ซับซ้อน
อย่างไรก็ตามฉันเชื่อว่าคำตอบว่าทำไมคำสั่งนี้:
$ IFS=. printf "%s\n" $var
a.b.c
ทำงานเหมือนที่เป็นแนวคิดง่ายๆที่บรรทัดคำสั่งทั้งหมดจะถูกวิเคราะห์คำก่อนที่จะถูกดำเนินการ และแต่ละคำนั้นถูกประมวลผลโดยเชลล์
การมอบหมายเช่นIFS=.นั้นล่าช้า (ขั้นตอนที่ 4 คืออันสุดท้าย):
4.- การกำหนดตัวแปรแต่ละรายการจะถูกขยาย ...
จนกระทั่งก่อนที่คำสั่งจะถูกดำเนินการและการขยายทั้งหมดในอาร์กิวเมนต์จะถูกประมวลผลก่อนเพื่อสร้างบรรทัดที่สามารถใช้งานได้นี้:
$ IFS=. printf "%s\n" a.b.c ## IFS=. goes to the environment.
a.b.c
ค่าของ$varถูกขยายด้วย IFS "เก่า" a.b.cก่อนที่คำสั่งprintfจะได้รับอาร์กิวเมนต์"%s\n"a.b.cและ
Eval
อาจมีการหน่วงเวลาหนึ่งระดับโดยeval:
$ IFS=. eval printf "'%s\n'" \$var
a
b
c
บรรทัดถูกแยกวิเคราะห์ (ครั้งที่ 1) และ 'IFS =' ถูกตั้งค่าเป็นสภาพแวดล้อมเช่นนี้:
$ printf '%s\n' $var
จากนั้นจะถูกแยกวิเคราะห์อีกครั้งสำหรับสิ่งนี้:
$ printf '%s\n' a b c
และดำเนินการกับสิ่งนี้:
a
b
c
ค่าของ$var(abc) ถูกแบ่งด้วยค่าของ IFS ที่ใช้งานอยู่:.คือแยกกับมูลค่าของไอเอฟเอในการใช้งาน:
สิ่งแวดล้อม
ส่วนที่ซับซ้อนและยุ่งยากคือสิ่งที่ใช้ได้ในสภาพแวดล้อมเมื่อ !!!
นั่นอธิบายได้ดีมากในส่วนแรกของคำตอบของ Gilles
พร้อมรายละเอียดเพิ่มเติม
เมื่อคำสั่งนี้ถูกดำเนินการ:
$ IFS=. arr=($var)
ค่าของ IFS จะถูกเก็บไว้ในสภาพแวดล้อมปัจจุบันใช่:
$ printf '<%s> ' "${arr[@]}" "$IFS"
<a> <b> <c> <.>
IFS สำหรับคำสั่งเดียว
แต่สามารถหลีกเลี่ยงได้: การตั้งค่า IFS สำหรับคำสั่งเดียว
$ IFS=. command eval arr\=\(\$var\)
$ printf '<%s> ' "${arr[@]}" "$IFS"
<a> <b> <c> <
>
IFSยังคงตั้งค่าเป็น." Eek หลังจากอ่านส่วนแรกนั่นก็สมเหตุสมผลแล้ว แต่ก่อนที่ฉันจะโพสต์คำถามนี้ฉันคงไม่คาดคิดเช่นนั้น