Sự khác biệt giữa lệnh dựng sẵn và lệnh không phải là gì?


72

Có sự khác biệt nội tại nào giữa một lệnh dựng sẵn và một lệnh khác có thể làm điều tương tự không?

ví dụ. Các nội dung có được điều trị "đặc biệt" không? ... Có ít chi phí hoạt động hơn không? .. hoặc họ chỉ đơn giản là 'được xây dựng'; như bảng điều khiển của chiếc xe của bạn?

... và có một danh sách (hiện tại) dứt khoát của các nội dung này không?

Câu trả lời:


90

Từ ý kiến ​​của bạn, bạn dường như bối rối về chính xác vỏ là gì. Nhân chịu trách nhiệm quản lý hệ thống. Đó là phần thực sự tải và chạy chương trình, truy cập tệp, cấp phát bộ nhớ, v.v. Nhưng kernel không có giao diện người dùng; bạn chỉ có thể giao tiếp với nó bằng cách sử dụng một chương trình khác làm trung gian.

Shell là một chương trình in lời nhắc, đọc một dòng đầu vào từ bạn và sau đó diễn giải nó dưới dạng một hoặc nhiều lệnh để thao tác các tệp hoặc chạy các chương trình khác. Trước khi phát minh ra GUI, shell là giao diện người dùng chính của HĐH. Trên MS-DOS, shell được gọi command.comvà rất ít người từng thử sử dụng một cái khác. Tuy nhiên, trên Unix, đã có nhiều shell mà người dùng có thể chọn.

Chúng có thể được chia thành 3 loại. Các shell tương thích với Bourne sử dụng cú pháp xuất phát từ shell Bourne ban đầu . Shell C sử dụng cú pháp từ shell C ban đầu . Sau đó, có các shell không điều kiện phát minh ra cú pháp của riêng chúng hoặc mượn một từ một số ngôn ngữ lập trình và thường ít phổ biến hơn nhiều so với hai loại đầu tiên.

Lệnh tích hợp đơn giản là một lệnh mà shell tự thực hiện, thay vì diễn giải nó như một yêu cầu tải và chạy một số chương trình khác. Điều này có hai tác dụng chính. Đầu tiên, nó thường nhanh hơn, vì tải và chạy chương trình cần có thời gian. Tất nhiên, lệnh chạy càng lâu, thời gian tải càng ít đáng kể so với thời gian chạy tổng thể (vì thời gian tải khá không đổi).

Thứ hai, một lệnh tích hợp có thể ảnh hưởng đến trạng thái bên trong của shell. Đó là lý do tại sao các lệnh như cd phải được tích hợp sẵn, bởi vì một chương trình bên ngoài không thể thay đổi thư mục hiện tại của trình bao. Các lệnh khác, như echo, có thể được tích hợp sẵn để đạt hiệu quả, nhưng không có lý do nội tại nào chúng không thể là các lệnh bên ngoài.

Những lệnh nào được tích hợp tùy thuộc vào trình bao mà bạn đang sử dụng. Bạn sẽ phải tham khảo tài liệu của nó để biết danh sách (ví dụ: bashcác lệnh dựng sẵn được liệt kê trong Chương 4 của hướng dẫn sử dụng ). Các typelệnh có thể cho bạn biết nếu một lệnh là built-in (nếu shell của bạn là POSIX tương thích), bởi vì POSIX đòi hỏi typecó một built-in. Nếu whichkhông phải là tích hợp trong trình bao của bạn, thì có lẽ nó sẽ không biết về phần tích hợp của trình bao của bạn, nhưng sẽ chỉ tìm các chương trình bên ngoài.


Các ứng dụng giao tiếp với kernel bằng cách phát hành các ngắt, thực sự.
Nathan Osman

11
@George: Các ứng dụng giao tiếp với kernel bằng cách phát hành các tòa nhà, tùy thuộc vào HĐH và kiến ​​trúc có thể hoặc không thể sử dụng các ngắt. Người dùng, theo quy định, không gây ra sự gián đoạn.
Gilles

2
@cjm: Nghe có vẻ đơn giản khi bạn giải thích như vậy :) ... bạn chắc chắn đã giúp xóa sương mù ... chỉ là một màn sương nhẹ .. (thực ra đó chỉ là thời tiết ở đây, sáng nay. .. sương mù dễ chịu;) ... cảm ơn
Peter.O

@Gilles: Thật sao? Tôi nghĩ rằng tất cả các chương trình chế độ người dùng giao tiếp với kernel thông qua các ngắt (tất nhiên trên các kiến ​​trúc nhất định).
Nathan Osman

2
@cjm Câu trả lời rất kỹ lưỡng và mang tính hướng dẫn. Tôi đã học được rất nhiều đọc nó. :)
ankush981

37

Có ba cấp độ tiện ích tích hợp:

  • Một số tiện ích thực sự là một phần của vỏ như một ngôn ngữ lập trình, mặc dù chúng không phải là từ dành riêng . Họ là những tiện ích dòng điều khiển ( ., :, break, continue, return, trap, exit, exec, eval), tiện ích thông số liên quan đến ( set, unset, shift, export, readonly, local¹, typeset¹), bí danh tiện ích ( alias², unalias²) và times³. Những tích hợp đặc biệt này được điều trị đặc biệt:

    • Nếu bạn chuyển các đối số sai sang một tích hợp đặc biệt, bản thân trình bao có thể hủy bỏ, thay vì chỉ bỏ qua lệnh tiếp theo sau khi hiển thị thông báo lỗi.
    • Cú pháp gán trước foo=bar utilitycó một ý nghĩa khác: đó là một phép gán tham số thông thường (nghĩa là tương đương với foo=bar; utility), thay vì chỉ gán cho môi trường trong suốt thời gian của tiện ích.
  • Một số tiện ích cần được triển khai bên trong shell vì chúng hoạt động trên các cài đặt bên trong của shell. Điêu nay bao gôm:

    • tiện ích mà hành động dựa trên thư mục hiện hành của vỏ như cd, dirs, pushd, popd;
    • tiện ích điều khiển công việc như bg, disown, fg, jobs, wait;
    • tiện ích mà đọc hoặc thao tác các thuộc tính vỏ khác như builtin, command, hash, read, type, ulimit, umask;
    • tiện ích liên quan đến tính năng tương tác, khi họ đang có mặt, chẳng hạn như fc, history, bind.
  • Một số tiện ích thường được thực hiện như xây dựng-in hoàn toàn cho hiệu suất : echo, printf, test, true, false.

Các shell tiên tiến như bash , kshzsh thường có nhiều tích hợp hơn, thường để thực hiện các tính năng không chuẩn (thường là để tương tác). Hướng dẫn sử dụng của mỗi shell sẽ cho bạn biết các lệnh được tích hợp sẵn, mặc dù một số shell ( ít nhất là zsh ) hỗ trợ các mô-đun có thể tải động có thể cung cấp nhiều tích hợp hơn.

¹ Unknown để POSIX, nhưng đặc biệt trong ksh và nhiều tiện ích khác.
² Thông thường trong POSIX, nhưng đặc biệt trong ksh và một số vỏ khác.
³ Trong ksh, timeslà một wrapper xung quanh timetừ khóa: nó là một bí danh cho { { time;} 2>&1;}. Lưu ý rằng POSIX cho phép timetrở thành một tiện ích bên ngoài với phân tích cú pháp thông thường hoặc từ khóa áp dụng cho toàn bộ đường ống (có trong ksh, bash in zsh).


3
Những sự phân biệt này là những người thực sự quan trọng.
dmckee

Câu hỏi nhanh, vậy "gán tham số thông thường" nghĩa là gì khi chúng ta làm gì while IFS= read -r line?
Sergiy Kolodyazhnyy

@SergiyKolodyazhnyy readkhông phải là nội dung đặc biệt, do đó, chỉ IFS=readđặt biến trong khoảng thời gian của lệnh.
Gilles

10

Nội dung là một lệnh được cung cấp bởi trình bao, chứ không phải bởi một chương trình bên ngoài. Dưới đây là danh sách bashcác nội dung của chúng (chúng cũng được liệt kê trong trang bash man) và zshcác nội dung của nó . kshcung cấp một danh sách bằng cách chạy builtin.

Để biết nếu một lệnh cụ thể là một dựng sẵn, bạn có thể chạy type command. Hãy thử type fortype lsđể thấy điều này.


typedường như làm mánh khóe; cảm ơn vì điều đó ... nhưng tôi vẫn tự hỏi "được cung cấp bởi cái vỏ" nghĩa là gì ... Có lẽ tôi cần hiểu đầy đủ hơn về cái vỏ liên quan đến hạt nhân .... nhưng không phải lúc 2 giờ sáng. Tôi sẽ đến trở lại vào ngày mai
Peter.O

1

Mỗi distro và shell có một tập hợp các lệnh khác nhau so với các hàm shell dựng sẵn. Nói chung, ý tưởng là shell tích hợp các chức năng phổ biến và đơn giản nhất để tiết kiệm thời gian, tốc độ và ý chí tích hợp với phần còn lại của bộ tính năng. Chi phí thấp hơn nhiều vì nó không phải khởi chạy một quy trình hệ thống khác. Tuy nhiên có thể trộn và kết hợp. Bạn có thể chạy một shell có bản dựng cho một cái gì đó, nhưng cũng có lệnh đó trên hệ thống của bạn. Thông thường các nội trang sẽ được ưu tiên, nhưng bạn có thể kiểm soát điều đó.

Bạn có thể dễ dàng tìm hiểu xem một lệnh cụ thể có phải là nội dung hay không bằng cách chạy type mycommand. Hầu hết các trang shell man cũng có một danh sách các nội trang của chúng.

Chỉnh sửa: Sử dụng typeđể tìm hiểu xem một lệnh có phải là nội dung không và nếu không whichtìm hiểu lệnh sẽ được thực thi từ đâu.


@Caleb: cảm ơn vì nhận xét của bạn, nhưng nó khiến tôi băn khoăn không biết chính xác "quy trình hệ thống" là gì .. Tôi cứ thấy các tài liệu tham khảo sau đó nhưng tôi không hiểu sự khác biệt là gì .... (btw Tôi không thể xem làm thế nào 'which' là một chỉ báo tuyệt đối) .. ví dụ .. 'mà echo =>"/bin/echo" and loại echo =>"echo is a shell builtin", but 'which dd=> "/ bin / dd" và type dd=> "dd is / bin / dd" ... vì vậy, tôi tham gia cách đó ....
Peter.O

"Hệ thống procses" chỉ có nghĩa là nó đang được khởi động như một ứng dụng độc lập được quản lý bởi kernel. Sự thay thế trong trường hợp các nội trang chỉ là chạy một hàm phụ trong mã đã chạy của trình bao của bạn. Trong ví dụ bạn đưa ra, typelà chỉ báo tốt hơn về những gì đang được chạy, nhưng bạn nhận thấy echocả hai đều là nội dung và có một ứng dụng có tên đó. Nếu hệ vỏ của bạn không được tích hợp sẵn, hệ thống sẽ chạy.
Caleb

2
whichkhông nhất thiết phải là một lệnh tích hợp và nếu không, nó sẽ không biết về các lệnh dựng sẵn của shell. POSIX yêu cầu đó typelà một lệnh tích hợp, vì vậy nó luôn biết về các lệnh dựng sẵn.
cjm

Nhiều hệ thống tàu với một bí danh của whichđể typehoặc một số thiết lập các tùy chọn ví dụ alias which='type -path'- điều này có thể là nguồn gốc của sự nhầm lẫn.
Random832

1
Tôi không thể nâng cao điều này, cho đến khi whichđược thay thế bằng type. Tôi đã sử dụng cái này, nhiều lần, không biết typevà rất ngạc nhiên khi nói dối, điều đó whichlà đúng, nếu quyết định giữa các chương trình.
người dùng không xác định
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.