อะไรคือความแตกต่างระหว่างคำสั่ง builtin และคำสั่งที่ไม่ได้ใช้?


72

มีความแตกต่างที่แท้จริงระหว่างคำสั่ง builtin และคำสั่งอื่นซึ่งในนามสามารถทำสิ่งเดียวกันในนาม?

เช่น. builtins ได้รับการบำบัดแบบพิเศษหรือไม่ ... มีค่าใช้จ่ายน้อยลงหรือไม่ .. หรือว่าพวกเขาเพียงแค่ 'สร้างขึ้นใน'; ชอบแดชบอร์ดของรถของคุณ?

... และมีรายการ (ปัจจุบัน) ที่ชัดเจนของ builtins เหล่านี้หรือไม่

คำตอบ:


90

จากความคิดเห็นของคุณดูเหมือนว่าคุณจะสับสนว่าเชลล์คืออะไร เคอร์เนลรับผิดชอบการจัดการระบบ เป็นส่วนที่โหลดและรันโปรแกรมเข้าถึงไฟล์จัดสรรหน่วยความจำ ฯลฯ แต่เคอร์เนลไม่มีส่วนต่อประสานผู้ใช้ คุณสามารถสื่อสารกับมันได้โดยใช้โปรแกรมอื่นเป็นสื่อกลาง

เชลล์เป็นโปรแกรมที่พิมพ์พรอมต์อ่านบรรทัดอินพุตจากคุณจากนั้นตีความมันเป็นคำสั่งอย่างน้อยหนึ่งคำสั่งเพื่อจัดการไฟล์หรือรันโปรแกรมอื่น ก่อนการประดิษฐ์ GUI เปลือกคือส่วนติดต่อผู้ใช้หลักของระบบปฏิบัติการ บน MS-DOS เชลล์นั้นถูกเรียกใช้command.comและมีคนเพียงไม่กี่คนที่เคยลองใช้อันอื่น อย่างไรก็ตามบน Unix มีเชลล์จำนวนมากที่ผู้ใช้สามารถเลือกได้

พวกเขาสามารถแบ่งออกเป็น 3 ประเภท เปลือกหอยบอร์นได้ใช้ไวยากรณ์ที่ได้มาจากเดิมที่บอร์นเชลล์ C เชลล์ใช้ไวยากรณ์จากC เชลล์ดั้งเดิม จากนั้นก็จะมีเชลล์แบบดั้งเดิมที่คิดค้นไวยากรณ์ของตัวเองหรือยืมมาจากภาษาการเขียนโปรแกรมบางอย่างและโดยทั่วไปจะได้รับความนิยมน้อยกว่าสองประเภทแรก

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

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

คำสั่งใดที่มีอยู่แล้วภายในจะขึ้นอยู่กับเชลล์ที่คุณใช้ คุณจะต้องศึกษาเอกสารประกอบของรายการ (เช่นbashคำสั่งในตัวของรายการอยู่ในบทที่ 4 ของคู่มือ ) typeคำสั่งสามารถบอกคุณได้ถ้าคำสั่งในตัว (ถ้าเปลือกของคุณเป็น POSIX ได้) เพราะ POSIX กำหนดว่าtypeจะเป็นในตัว หากwhichไม่ใช่ built-in ในเชลล์คุณอาจไม่รู้เกี่ยวกับ built-in ของ shell แต่จะค้นหาโปรแกรมภายนอก


แอปพลิเคชันสื่อสารกับเคอร์เนลโดยการออกอินเตอร์รัปต์จริง ๆ
Nathan Osman

11
@George: แอปพลิเคชันสื่อสารกับเคอร์เนลโดยการออก syscalls ซึ่งขึ้นอยู่กับระบบปฏิบัติการและสถาปัตยกรรมอาจหรือไม่ใช้อินเตอร์รัปต์ ผู้ใช้ตามกฎแล้วจะไม่ออกการขัดจังหวะ
Gilles

2
@cjm: ฟังดูง่ายมากเมื่อคุณอธิบายแบบนั้น:) ... คุณช่วยล้างหมอกได้อย่างแน่นอน ... แค่มีหมอกบาง ๆ ในตอนนี้ .. (อันที่จริงแล้วมันเป็นแค่สภาพอากาศที่นี่เช้านี้) .. มีหมอกสบาย ๆ ;) ... ขอบคุณ
Peter.O

@Gilles: จริงเหรอ? ฉันคิดว่าโปรแกรมโหมดผู้ใช้ทั้งหมดสื่อสารกับเคอร์เนลผ่านการขัดจังหวะ (แน่นอนในสถาปัตยกรรมบางอย่าง)
Nathan Osman

2
@cjm คำตอบที่ละเอียดและให้คำแนะนำอย่างละเอียดมาก ฉันได้เรียนรู้มากมายจากการอ่าน :)
ankush981

37

ยูทิลิตี้ในตัวมีสามระดับ:

  • สาธารณูปโภคบางจริงๆส่วนหนึ่งของเปลือกเป็นภาษาโปรแกรมที่ถึงแม้ว่าพวกเขาไม่ได้เป็นคำสงวน พวกเขาเป็นสาธารณูปโภคการควบคุมการไหล ( ., :, break, continue, return, trap, exit, exec, eval) สาธารณูปโภคพารามิเตอร์ที่เกี่ยวข้องกัน ( set, unset, shift, export, readonly, local¹, typeset¹) สาธารณูปโภคนามแฝง ( alias², unalias²) และtimes³ บิวด์อินพิเศษเหล่านี้ได้รับการดูแลเป็นพิเศษ:

    • หากคุณส่งอาร์กิวเมนต์ที่ไม่ถูกต้องไปยังบิวด์อินพิเศษเชลล์เองอาจยกเลิกได้แทนที่จะข้ามไปยังคำสั่งถัดไปหลังจากแสดงข้อความแสดงข้อผิดพลาด
    • ไวยากรณ์การกำหนดล่วงหน้าfoo=bar utilityมีความหมายแตกต่างกัน: เป็นการกำหนดพารามิเตอร์ทั่วไป (เช่นเทียบเท่าfoo=bar; utility) แทนที่จะกำหนดให้กับสภาพแวดล้อมในช่วงระยะเวลาของยูทิลิตี้เท่านั้น
  • ยูทิลิตี้บางอย่างจำเป็นต้องดำเนินการภายในเชลล์เนื่องจากมันทำหน้าที่เกี่ยวกับการตั้งค่าภายในของเชลล์ รวมถึง:

    • ระบบสาธารณูปโภคที่ทำหน้าที่เกี่ยวกับไดเรกทอรีปัจจุบันของเปลือกเช่นcd, dirs, pushd, popd;
    • สาธารณูปโภคควบคุมงานเช่นbg, disown, fg, jobs, wait;
    • ระบบสาธารณูปโภคที่อ่านหรือจัดการคุณลักษณะเปลือกอื่น ๆ เช่นbuiltin, command, hash, read, type, ulimit, umask;
    • สาธารณูปโภคที่เกี่ยวข้องกับคุณลักษณะแบบโต้ตอบเมื่อพวกเขากำลังในปัจจุบันเช่นfc, ,historybind
  • สาธารณูปโภคบางส่วนจะดำเนินการมักจะเป็นตัวอินหมดจดสำหรับผลการดำเนินงาน : echo, printf, test, ,truefalse

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

¹ ไม่รู้จัก POSIX แต่พิเศษเป็น ksh และเชลล์อื่น ๆ
² ธรรมดาใน POSIX แต่พิเศษใน ksh และเปลือกหอยอื่น ๆ
³ ในksh, timesเป็นเสื้อคลุมรอบtimeคำสำคัญ: { { time;} 2>&1;}มันเป็นนามแฝงสำหรับ โปรดทราบว่า POSIX อนุญาตให้timeเป็นยูทิลิตี้ภายนอกที่มีการแยกวิเคราะห์ทั่วไปหรือคำหลักที่ใช้กับไปป์ไลน์ทั้งหมด (ซึ่งอยู่ใน ksh, bash in zsh)


3
ความแตกต่างเหล่านี้เป็นสิ่งที่สำคัญจริงๆ
dmckee

คำถามอย่างรวดเร็วเพื่อให้สิ่งที่ไม่ "การกำหนดค่าพารามิเตอร์ธรรมดา" หมายถึงเมื่อเราทำwhile IFS= read -r line?
Sergiy Kolodyazhnyy

@SergiyKolodyazhnyy readไม่ใช่ builtin พิเศษดังนั้นให้IFS=readตั้งค่าตัวแปรสำหรับช่วงเวลาของคำสั่งเท่านั้น
Gilles

10

builtin เป็นคำสั่งที่จัดทำโดยเชลล์แทนที่จะเป็นโปรแกรมภายนอก นี่คือรายการสำหรับbashbuiltins ของ (รายการเหล่านี้จะปรากฏในหน้า bash man) และzshbuiltinsของ ให้รายการโดยใช้kshbuiltin

type commandจะทราบว่าคำสั่งโดยเฉพาะอย่างยิ่งเป็นในตัวคุณสามารถเรียกใช้ ลองtype forและtype lsดูสิ่งนี้


typeดูเหมือนว่าจะทำเคล็ดลับ; ขอบคุณสำหรับการที่ ... แต่ฉันยังคงสงสัยว่า "เปลือกหอยให้" หมายถึง ... บางทีฉันต้องเข้าใจอย่างถ่องแท้ว่าเชลล์เกี่ยวข้องกับเคอร์เนลอย่างไร .... แต่ไม่ใช่ตอนตี 2 .. ฉันจะมา กลับมาพรุ่งนี้นี้
Peter

1

ทุก distro และ shell มีชุดคำสั่งที่แตกต่างกันและฟังก์ชั่นเชลล์ในตัว โดยทั่วไปแล้วความคิดคือเชลล์สร้างในฟังก์ชั่นทั่วไปและง่ายที่สุดเพื่อประหยัดเวลาความเร็วและการรวมเข้าด้วยกันกับส่วนที่เหลือของชุดคุณสมบัติ ค่าใช้จ่ายต่ำกว่ามากเนื่องจากไม่จำเป็นต้องเปิดใช้กระบวนการของระบบอื่น อย่างไรก็ตามมันเป็นไปได้ที่จะผสมและจับคู่ คุณอาจเรียกใช้หนึ่งเชลล์ที่มี buildin สำหรับบางสิ่ง แต่มีคำสั่งนั้นในระบบของคุณด้วย โดยปกติแล้วตัวในจะให้ความสำคัญ แต่คุณสามารถควบคุมได้

คุณสามารถหาได้ง่ายไม่ว่าจะเป็นคำสั่งที่ระบุเป็น builtin type mycommandหรือไม่โดยการเรียกใช้ เชลล์แมนเพจส่วนใหญ่มีรายการบิวด์อินด้วย

แก้ไข:ใช้typeเพื่อค้นหาว่าคำสั่งนั้นเป็นตัวภายในหรือไม่และหากไม่whichต้องการเรียนรู้ว่าคำสั่งนั้นจะถูกเรียกใช้จากที่ใด


@Caleb: ขอบคุณสำหรับความคิดเห็นของคุณ แต่มันทำให้ฉันสงสัยเกี่ยวกับสิ่งที่ "กระบวนการของระบบ" คือ .. ฉันยังคงเห็นการอ้างอิงถึงแล้ว แต่ฉันไม่เข้าใจว่ามีความแตกต่างอยู่ .... (btw ฉันไม่สามารถ ดูว่า 'ไหน' เป็นตัวบ่งชี้ที่แน่นอน) .. เช่น .. 'echo =>"/bin/echo" and type echo =>"echo is a shell builtin", but 'which dd=> "/ bin / dd" และtype dd=> "dd is / bin / dd" ... ดังนั้นฉันมีส่วนร่วม ....
Peter.O

"System procses" เพียงหมายความว่ากำลังเริ่มต้นขึ้นเป็นแอปพลิเคชันอิสระที่จัดการโดยเคอร์เนล ทางเลือกในกรณีของ builtins เป็นเพียงการเรียกใช้ฟังก์ชั่นย่อยในรหัสที่ทำงานอยู่แล้วของเชลล์ของคุณ ในตัวอย่างที่คุณให้typeเป็นตัวบ่งชี้ที่ดีกว่าของสิ่งที่กำลังทำงาน แต่คุณสังเกตเห็นechoว่าทั้ง builtin และมีแอปพลิเคชันที่มีชื่อนั้น หากเชลล์ของคุณไม่มี builtin ระบบก็จะรัน
Caleb

2
whichไม่จำเป็นต้องเป็นคำสั่งในตัวและหากไม่มีก็จะไม่ทราบเกี่ยวกับตัวบิวด์อินของเชลล์ POSIX ต้องการtypeให้เป็นคำสั่งในตัวดังนั้นมันจึงรู้เกี่ยวกับบิวด์อินเสมอ
cjm

ระบบจำนวนมากมาพร้อมกับนามแฝงwhichถึงtypeหรือชุดของตัวเลือกบางอย่างเช่นalias which='type -path'- ซึ่งอาจเป็นแหล่งของความสับสน
Random832

1
ฉันไม่สามารถ upvote นี้จนกว่าจะถูกแทนที่ด้วยwhich typeฉันใช้ซึ่งซ้ำแล้วซ้ำอีกไม่รู้typeและประหลาดใจมากที่จะเรียนรู้ที่whichเหมาะสมเท่านั้นหากตัดสินใจระหว่างโปรแกรม
ผู้ใช้ที่ไม่รู้จัก
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.