เหตุใด POSIX จึงต้องมีเชลล์ในตัวเพื่อให้มีการใช้งานภายนอก


18

จากคำถามนี้เกี่ยวกับว่าเป็น printf ในตัวสำหรับ Yashมาคำตอบนี้ว่าคำพูดมาตรฐาน POSIX

คำตอบนั้นชี้ให้เห็นว่าลำดับการค้นหา POSIX คือการค้นหาการนำไปใช้ภายนอกของคำสั่งที่ต้องการและจากนั้นหากเชลล์นำมาใช้เป็นแบบบิวด์อินให้รันบิวด์อิน (สำหรับบิวด์อินที่ไม่ใช่บิวด์อินพิเศษ)

เหตุใด POSIX จึงมีข้อกำหนดนี้เพื่อให้มีการใช้งานภายนอกอยู่ก่อนที่จะอนุญาตให้มีการใช้งานภายในได้

ดูเหมือน ... โดยพลการดังนั้นฉันอยากรู้


ฉันเชื่อว่าเป็นวิธีการเปิด / ปิดการใช้งานบิวอินหากต้องการ / จำเป็น
ไอแซค

2
ปิดการใช้งานบิวด์อินด้วยการลบการใช้งานภายนอกหรือไม่ ตอนนี้ไม่มีคำสั่งของชื่อprintfพร้อมใช้งาน
ศึกษา

@studog ดังนั้นให้สร้างไฟล์เปล่าที่มีชื่อเดียวกับในตัวเปิดบิตดำเนินการและวางไว้ในไดเรกทอรีใน PATH ของคุณ : P
สัญลักษณ์แทน

@Wildcard เชลล์ที่สอดคล้องอย่างเคร่งครัดจะเห็นชื่อขณะค้นหาPATHและจากนั้นเรียกใช้ยูทิลิตี้ในตัวไม่ใช่สคริปต์ภายนอก ถ้าคุณต้องการเรียกสคริปต์ภายนอกในเส้นทางของคุณ อืม ... นี่ดูเหมือนจะเป็นตารางที่อธิบายความเป็นไปได้ต่าง ๆ มีอยู่ที่นี่แต่มันก็ไม่สมเหตุสมผลสำหรับฉัน
Kusalananda

@ Kusalananda ประโยคแรกของคุณนั่นคือประเด็นของฉัน ดังนั้นทำไมฉันบอกว่าจะสร้างไฟล์ที่ว่างเปล่า
ไวด์การ์ด

คำตอบ:


15

นี่เป็นกฎ "ราวกับว่า"

ใส่เพียง: พฤติกรรมของเชลล์ตามที่ผู้ใช้เห็นว่ามันไม่ควรเปลี่ยนแปลงหากการดำเนินการตัดสินใจที่จะทำให้คำสั่งภายนอกมาตรฐานยังมีอยู่ในตัวเชลล์

ความแตกต่างที่ฉันแสดงให้เห็นที่/unix//a/496291/5132ระหว่างพฤติกรรมของ (ในมือข้างหนึ่ง) PD Korn, MirBSD Korn และหอย Heirloom Bourne; (ในทางกลับกัน) Z, 93 Korn, Bourne Again และ Debian Almquist shells; และ (ในมือที่จับได้) เปลือกวาตานาเบะเน้นเรื่องนี้

สำหรับเปลือกหอยที่ไม่ได้printfเป็นในตัวออก/usr/binจากการPATHทำให้การภาวนาของprintfหยุดทำงาน พฤติกรรมที่สอดคล้องกับ POSIX ซึ่งแสดงโดยเปลือกวาตานาเบะในโหมดที่เข้ากันได้ทำให้เกิดผลลัพธ์ที่เหมือนกัน พฤติกรรมของเชลล์ที่มีprintfอยู่แล้วภายในจะเหมือนกับว่าถูกเรียกใช้คำสั่งภายนอก

ในขณะที่พฤติกรรมของเชลล์ที่ไม่สอดคล้องทั้งหมดจะไม่เปลี่ยนแปลงหาก/usr/binถูกลบออกจากPATHและพวกเขาจะไม่ทำงานเหมือนกับว่าพวกเขาถูกเรียกใช้คำสั่งภายนอก

สิ่งที่มาตรฐานพยายามรับประกันให้คุณคือเชลล์สามารถสร้างคำสั่งภายนอกได้ทุกประเภท (หรือใช้มันเป็นฟังก์ชั่นเชลล์ของตัวเอง) และคุณจะยังคงได้รับพฤติกรรมเดียวกันจากบิวด์อินเช่นที่คุณทำ ด้วยคำสั่งภายนอกหากคุณปรับPATHเพื่อหยุดคำสั่งจากการถูกพบ PATHยังคงเป็นเครื่องมือในการเลือกและควบคุมคำสั่งที่คุณสามารถเรียกใช้

(ตามที่อธิบายไว้ที่/unix//a/448799/5132หลายปีก่อนผู้คนเลือกบุคลิกภาพของ Unix ของพวกเขาโดยการเปลี่ยนสิ่งที่เกิดPATHขึ้น)

อาจมีความคิดเห็นที่ทำให้คำสั่งทำงานโดยไม่คำนึงถึงว่าสามารถพบได้PATH ในความเป็นจริงจุดของการสร้างคำสั่งภายนอกตามปกติในตัว (นั่นเป็นสาเหตุที่ชุดเครื่องมือ nosh ของฉันเพิ่งได้printenvรับคำสั่งในตัวในเวอร์ชัน 1.38 จริง ๆ แล้วแม้ว่านี่ไม่ใช่เชลล์)

แต่มาตรฐานจะให้การรับประกันกับคุณว่าคุณจะเห็นพฤติกรรมแบบเดียวกันสำหรับคำสั่งภายนอกทั่วไปที่ไม่ได้อยู่PATHในเชลล์คุณจะเห็นจากโปรแกรมอื่นที่ไม่ใช่เชลล์ที่เรียกใช้execvpe()ฟังก์ชันและเชลล์จะไม่สามารถใช้เวทมนตร์ได้อย่างน่าอัศจรรย์ รัน (เห็นได้ชัด) คำสั่งภายนอกธรรมดาที่โปรแกรมอื่น ๆ PATHที่ไม่สามารถหาด้วยเหมือนกัน ทุกอย่างทำงานด้วยตนเองอย่างสม่ำเสมอจากมุมมองของผู้ใช้และPATHเป็นเครื่องมือสำหรับควบคุมวิธีการทำงาน

อ่านเพิ่มเติม


13

มันค่อนข้างไร้สาระและนั่นเป็นสาเหตุที่ไม่มีการใช้งานเชลล์ในโหมดเริ่มต้น

มาตรฐานของเหตุผลและแสดงตนเป็นตัวอย่างแสดงให้เห็นว่าเรื่องนี้เป็นความพยายามที่ไม่เรียบร้อยจะมีความปกติในตัวที่เกี่ยวข้องกับเส้นทางและให้แทนที่ผู้ใช้มันโดยมีไบนารีของตัวเองปรากฏก่อนที่มันในPATH(เช่น a. printfในตัวที่เกี่ยวข้องกับ/usr/bin/printfอาจถูกแทนที่โดย/foo/bin/printfคำสั่งภายนอกโดยการตั้งค่าPATH=/foo/bin:$PATH)

อย่างไรก็ตามมาตรฐานไม่ได้ต้องการสิ่งนั้น แต่มีบางอย่างที่แตกต่างอย่างสิ้นเชิง (และไร้ประโยชน์และไม่คาดคิด)

คุณสามารถอ่านเพิ่มเติมเกี่ยวกับเรื่องนี้ในรายงานข้อผิดพลาดนี้ การอ้างอิงจากข้อความที่ได้รับการยอมรับขั้นสุดท้าย :

การใช้งานที่มีอยู่จำนวนมากดำเนินการในตัวปกติโดยไม่ต้องทำการค้นหา PATH พฤติกรรมนี้ไม่ตรงกับข้อความเชิงบรรทัดฐานและไม่อนุญาตให้ผู้เขียนสคริปต์แทนที่ยูทิลิตี้ในตัวปกติผ่านทาง PATH ที่สร้างขึ้นเป็นพิเศษ นอกจากนี้เหตุผลอธิบายว่าความตั้งใจที่จะช่วยให้ผู้เขียนไปแทนที่ ตัว -ins โดยการปรับเปลี่ยนเส้นทาง แต่นี่ไม่ใช่สิ่งที่ข้อความกฎเกณฑ์กล่าวว่า

FWIW ฉันไม่คิดว่ามีเชลล์ใดที่ใช้ข้อกำหนดที่ปรับปรุงใหม่จากข้อความที่ยอมรับเช่นกัน


ดูการอภิปรายได้ที่article.gmane.org/gmane.comp.standards.posix.austin.general/ … (และมีอีกหลายคน)
Stéphane Chazelas

นอกจากนี้github.com/att/ast/issues/370 (ยาว)
Stéphane Chazelas

ไม่(เช่นในตัว printf ที่เชื่อมโยงกับ / usr / bin / printf อาจถูกเขียนทับโดยคำสั่งภายนอก / foo / bin / printf โดยการตั้งค่า PATH = / foo / bin: $ PATH) นั่นไม่ถูกต้อง การมีอยู่ของ / / / / ใด ๆ/usr/bin/printfหรือ/foo/bin/printfใน PATH จะเปิดใช้งานbuiltin printf สิ่งเดียวที่ขาดหายไป (ในเส้นทาง) ภายนอกprintfจะทำคือการปิดการใช้งาน builtin (ตามตัวอักษรของสเป็ค)
Isaac
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.