Tại sao POSIX yêu cầu các trình dựng sẵn nhất định phải có triển khai bên ngoài?


18

Từ câu hỏi này về việc printf có tích hợp sẵn cho yash hay không , đi đến câu trả lời này trích dẫn tiêu chuẩn POSIX .

Câu trả lời chỉ ra rằng chuỗi tìm kiếm POSIX là tìm một triển khai bên ngoài của lệnh mong muốn, và sau đó, nếu shell đã triển khai nó dưới dạng tích hợp, hãy chạy tích hợp. (Đối với các phần dựng sẵn không phải là phần dựng đặc biệt .)

Tại sao POSIX có yêu cầu này đối với việc triển khai bên ngoài tồn tại trước khi cho phép chạy triển khai nội bộ?

Có vẻ như ... tùy tiện, nên tôi tò mò.


Tôi tin rằng đó là một cách để bật / tắt các nội dung nếu muốn / yêu cầu.
Isaac

2
Vô hiệu hóa tích hợp bằng cách loại bỏ việc thực hiện bên ngoài? Bây giờ không có lệnh tên printfcó sẵn.
studog

@studog, vì vậy hãy tạo một tệp trống có cùng tên với tích hợp sẵn, bật bit thực thi và đặt nó vào một thư mục trong PATH của bạn. : P
tự đại diện

@Wildcard Một shell tuân thủ nghiêm ngặt sau đó sẽ thấy tên trong khi tìm kiếm PATHvà sau đó gọi tiện ích tích hợp, không phải là tập lệnh bên ngoài. Điều gì nếu bạn muốn gọi tập lệnh bên ngoài trong đường dẫn của bạn? Hmm ... Điều này dường như gọi cho một bảng mô tả các khả năng khác nhau. Có một cái ở đây , nhưng nó không có ý nghĩa với tôi.
Kusalananda

@Kusalananda, lại là câu đầu tiên của bạn, đó là quan điểm của tôi. Do đó tại sao tôi nói để tạo một tập tin trống .
tự đại diện

Câu trả lời:


15

Đây là một quy tắc "như thể".

Nói một cách đơn giản: Hành vi của shell khi người dùng thấy nó không nên thay đổi nếu việc triển khai quyết định tạo một lệnh bên ngoài tiêu chuẩn cũng có sẵn dưới dạng shell tích hợp.

Sự tương phản mà tôi đã thể hiện tại /unix//a/496291/5132 giữa các hành vi của (một mặt) các vỏ PD Korn, MirBSD Korn và Heirloom Bourne; (mặt khác) các vỏ đạn Z, 93 Korn, Bourne Again và Debian Almquist; và (trên bàn tay nắm chặt) vỏ Watanabe làm nổi bật điều này.

Đối với các shell không printfđược tích hợp sẵn, việc xóa /usr/binkhỏi sẽ PATHtạo ra một lệnh printfngừng hoạt động. Hành vi tuân thủ POSIX, được thể hiện bởi vỏ Watanabe trong chế độ tuân thủ của nó, gây ra kết quả tương tự. Hành vi của shell có tích printfhợp sẵn như thể nó đang gọi một lệnh bên ngoài.

Trong khi đó hành vi của tất cả các shell không tuân thủ sẽ không thay đổi nếu /usr/binbị xóa khỏi PATHvà chúng không hoạt động như thể chúng đang gọi một lệnh bên ngoài.

Điều mà tiêu chuẩn đang cố gắng đảm bảo với bạn là các shell có thể tích hợp tất cả các loại lệnh bên ngoài thông thường (hoặc thực hiện chúng như các hàm shell riêng của nó) và bạn vẫn sẽ có hành vi tương tự từ các hàm dựng sẵn như bạn đã làm với các lệnh bên ngoài nếu bạn điều chỉnh PATHđể ngăn chặn các lệnh được tìm thấy. PATHvẫn là công cụ của bạn để chọn và kiểm soát những lệnh bạn có thể gọi.

(Như đã giải thích tại /unix//a/448799/5132 , nhiều năm trước mọi người đã chọn tính cách của Unix bằng cách thay đổi những gì đang diễn ra PATH.)

Người ta có thể thấy rằng làm cho lệnh luôn hoạt động bất kể nó có thể được tìm thấy trên PATH thực tế là điểm tạo ra các lệnh bên ngoài thông thường được tích hợp. (Đó là lý do tại sao bộ công cụ nosh của tôi vừa đạt được một printenvlệnh tích hợp trong phiên bản 1.38, trên thực tế. Mặc dù đây không phải là một trình bao.)

Nhưng tiêu chuẩn mang đến cho bạn sự đảm bảo rằng bạn sẽ thấy hành vi tương tự đối với các lệnh bên ngoài thông thường không có trên PATHshell như bạn sẽ thấy từ các chương trình không phải shell khác gọi execvpe()hàm và shell sẽ không thể thực hiện được chạy (dường như) các lệnh bên ngoài thông thường mà các chương trình khác không thể tìm thấy cùng PATH. Mọi thứ hoạt động tự nhất quán theo quan điểm của người dùng và PATHlà công cụ để kiểm soát cách thức hoạt động của nó.

đọc thêm


13

Điều đó khá vô lý và đó là lý do tại sao không có trình bao nào thực hiện nó trong chế độ mặc định của nó.

sở lý luận của tiêu chuẩn và ví dụ minh họa của nó cho thấy rằng đây là một nỗ lực đã được khắc phục để có một tích hợp thường xuyên được liên kết với một đường dẫn và để người dùng ghi đè lên nó bằng cách có nhị phân riêng xuất hiện trước nó PATH(ví dụ: tích printfhợp sẵn /usr/bin/printfcó thể bị ghi đè bởi /foo/bin/printflệnh bên ngoài bằng cách cài đặt PATH=/foo/bin:$PATH).

Tuy nhiên, tiêu chuẩn cuối cùng không yêu cầu điều đó, nhưng một cái gì đó hoàn toàn khác (và cũng vô dụng và bất ngờ).

Bạn có thể đọc thêm về nó trong báo cáo lỗi này . Trích dẫn từ văn bản được chấp nhận cuối cùng :

Nhiều triển khai hiện có thực thi tích hợp thường xuyên mà không thực hiện tìm kiếm PATH. Hành vi này không phù hợp với văn bản quy phạm và nó không cho phép các tác giả kịch bản ghi đè các tiện ích tích hợp thông thường thông qua một PATH được chế tạo đặc biệt. Ngoài ra, lý do giải thích rằng ý định là cho phép các tác giả ghi đè lên các phần dựng sẵn bằng cách sửa đổi PATH, nhưng đây không phải là những gì văn bản quy phạm nói .

FWIW, tôi cũng không nghĩ có bất kỳ vỏ nào thực hiện các yêu cầu sửa đổi từ văn bản được chấp nhận.


Xem thêm các cuộc thảo luận tại article.gmane.org/gmane.comp.stiterias.poseix.austin.general/ ((và đã có một số người khác).
Stéphane Chazelas


Không, (ví dụ: một printf tích hợp liên kết với / usr / bin / printf có thể bị ghi đè bởi lệnh bên ngoài / foo / bin / printf bằng cách đặt PATH = / foo / bin: $ PATH). , đó là không chính xác. Sự tồn tại của một trong hai hoặc bất kỳ /usr/bin/printfhoặc /foo/bin/printftrong PATH sẽ kích hoạt bản in dựng sẵn . Điều duy nhất mà một bên ngoài bị thiếu (trong PATH) printfsẽ làm là vô hiệu hóa nội dung. (Bằng thư của thông số kỹ thuật).
Isaac
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.