สคริปต์ที่คล้ายกันโดยไม่มีsudoแต่ผลลัพธ์ที่คล้ายกัน:
$ cat script.sh
#!/bin/bash
sed -e 's/^/--/'
whoami
$ bash < script.sh
--whoami
$ dash < script.sh
itvirta
ด้วยbashส่วนที่เหลือของสคริปต์ไปเป็นข้อมูลป้อนเข้าsedด้วยdashเชลล์ตีความมัน
ทำงานstraceกับสิ่งเหล่านั้น: dashอ่านบล็อกของสคริปต์ (แปด kB ที่นี่มากกว่าพอที่จะเก็บสคริปต์ทั้งหมด) แล้ววางไข่sed:
read(0, "#!/bin/bash\nsed -e 's/^/--/'\nwho"..., 8192) = 36
stat("/bin/sed", {st_mode=S_IFREG|0755, st_size=73416, ...}) = 0
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|...
ซึ่งหมายความว่า filehandle อยู่ท้ายไฟล์และsedจะไม่เห็นอินพุตใด ๆ dashส่วนที่เหลือถูกบัฟเฟอร์ภายใน (หากสคริปต์ยาวกว่าขนาดบล็อก 8 kB ส่วนที่เหลือจะถูกอ่านด้วยsed)
ในทางกลับกัน Bash จะค้นหากลับไปที่ส่วนท้ายของคำสั่งสุดท้าย:
read(0, "#!/bin/bash\nsed -e 's/^/--/'\nwho"..., 36) = 36
stat("/bin/sed", {st_mode=S_IFREG|0755, st_size=73416, ...}) = 0
...
lseek(0, -7, SEEK_CUR) = 29
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|...
หากอินพุตมาจากไพพ์เช่นเดียวกับที่นี่:
$ cat script.sh | bash
ไม่สามารถกรอกลับได้เนื่องจากท่อและซ็อกเก็ตหาไม่ได้ ในกรณีนี้ Bash จะกลับไปอ่านอินพุตทีละตัวเพื่อหลีกเลี่ยงการโอเวอร์เฮด ( fd_to_buffered_stream()ในinput.c ) ทำการโทรแบบเต็มระบบสำหรับแต่ละไบต์ไม่ได้มีประสิทธิภาพมากในหลักการ ในทางปฏิบัติฉันไม่คิดว่าการอ่านจะเป็นค่าใช้จ่ายที่ดีเมื่อเทียบกับความจริงที่ว่าสิ่งที่เชลล์ส่วนใหญ่เกี่ยวข้องกับการวางไข่กระบวนการใหม่ทั้งหมด
สถานการณ์คล้ายกันคือ:
echo -e 'foo\nbar\ndoo' | bash -c 'read a; head -1'
เชลล์ย่อยต้องตรวจสอบให้แน่ใจว่าreadอ่านขึ้นบรรทัดใหม่แรกเท่านั้นเพื่อให้headเห็นบรรทัดถัดไป (ใช้ได้กับdashด้วย)
กล่าวอีกนัยหนึ่งทุบตีไปที่ความยาวเพิ่มเติมเพื่อรองรับการอ่านแหล่งเดียวกันสำหรับสคริปต์ตัวเองและสำหรับคำสั่งดำเนินการจากมัน dashไม่ zshและksh93บรรจุใน Debian ไปกับทุบตีเกี่ยวกับเรื่องนี้
sudo su: unix.stackexchange.com/questions/218169/…