Khi sh là một liên kết tượng trưng cho bash hoặc dash, bash tự giới hạn tuân thủ POSIX, vì vậy nó phải tương thích 100% với sh?


8

Từ sự khác biệt giữa bash và sh :

Trả lời câu hỏi: Nếu bạn có /bin/shliên kết đến bash, thì bash sẽ không hoạt động giống như khi được gọi như /bin/shkhi nó được gọi là /bin/bash. Khi được gọi là sh, nó sẽ tự giới hạn ở hầu hết tuân thủ POSIX cộng với một bộ tiện ích mở rộng hạn chế.

Điều đó có nghĩa là bất cứ khi nào tôi bắt gặp một tập lệnh shell trong Linux với shebang to sh : #!/bin/sh, ngay cả khi trên bản phân phối đó, bin/shlà một liên kết tượng trưng đến một shell khác, như dash hoặc bash, nó phải tương thích 100% với shell bourne, vì nó giới hạn bản thân trong một bộ mở rộng giới hạn? Vì vậy, tôi có thể thực hiện chúng trong FreeBSD? Có ngoại lệ cho điều đó? Hoặc tôi nên an toàn để cho rằng nó sẽ hoạt động?

Vì vậy, nếu trên một bản phân phối, bin/shlà một liên kết tượng trưng bin/bashvà sử dụng tập lệnh #!/bin/shvà tập lệnh chứa bashism, nó sẽ không chạy, vì bash sẽ thích ở chế độ sh?

Câu trả lời:


16

Không, nếu /bin/shlà một liên kết tượng trưng đến bash bash chỉ vào chế độ posix - từ man bash :

Khi được gọi là sh, bash sẽ chuyển sang chế độ posix sau khi các tệp khởi động được đọc.

Nếu bây giờ bạn tìm kiếm chế độ posix tại trang bash, bạn sẽ thấy rằng một số nội dung shell thích timehoặc sourcehoạt động khác nhau. Đó là tất cả. bashishms như viết functiontrước khi khai báo một hàm hoặc sử dụng sourcethay vì .vẫn sẽ hoạt động nhưng các lệnh có thể hoạt động khác nhau.

Vì vậy, nếu /bin/shlà một liên kết tượng trưng cho /bin/bashtất cả các bashishms điển hình vẫn hoạt động.

Để biết danh sách khá nhiều sự khác biệt trong chế độ Posix, hãy xem hướng dẫn tham khảo bash .


Vì vậy, tôi đoán điều tốt nhất để làm là kiểm tra tất cả các tập lệnh trong công cụ checkbashism. Tôi nghe nói rằng một số bản phân phối, như Debian và Ubuntu (cần xác nhận cho bản này) đã có liên kết biểu tượng bin / sh của họ bây giờ. Liệu dash có tương thích với vỏ bẻ khóa không? Nếu có, thì ít nhất tất cả các tập lệnh shell Debian và Ubuntu sẽ ổn trong FreeBSD.
dùng1115057

@ user1115057 chỉ các kịch bản shell với /bin/shnhư shebang. Một kịch bản shell vẫn có thể sử dụng rõ ràng /bin/bash. Dù sao, hầu hết các tập lệnh shell có thể sẽ chạy tốt trong / bin / sh, nhưng vấn đề sẽ là các công cụ người dùng, ví dụ: hầu hết các tập lệnh shell mong đợi vùng người dùng GNU có thể sẽ gặp nhiều vấn đề hơn là chỉ một số lỗi cú pháp. Tôi cũng đã thêm một liên kết đến tham chiếu bash liệt kê các hành vi khác nhau trong chế độ posix
Ulrich Dangel

Ok từ những gì tôi đọc được, BSD sử dụng tro làm thùng / sh của họ, trong khi Debian và Ubuntu sử dụng dấu gạch ngang. Nếu các shell đó tương thích, điều đó có nghĩa là tôi sẽ không gặp vấn đề gì nữa với shebang #! / Bin / sh. Nhưng như bạn đã nói, sẽ có vấn đề khác liên quan đến vùng người dùng ...
user1115057

@ user1115057 dấu gạch ngang cũng không hoàn thiện, ví dụ như wiki.ubuntu.com/DashAsBinSh/#echo kịch bản nào shell nhất khá đơn giản và có thể được chuyển khá dễ dàng ... chúc may mắn
Ulrich Dangel

Nhưng dash và tro là tương thích phải không?
dùng1115057

8

Dường như có một số nhầm lẫn xung quanh vỏ Bourne. Shell Bourne là shell Unix từ nhiều thập kỷ trước, trong những ngày trước POSIX. Ngày nay "sh" là một triển khai hoặc một lớp vỏ khác thực hiện đặc tả POSIX, trong đó chúng tôi có bash, pdksh, AT & T ksh, shell Almquist mới hơn và các dẫn xuất của chúng đã được tuân thủ POSIX (bao gồm cả "sh" của một số BSD , các BSD khác sẽ dựa trên pdksh và Debian ash (dash)). Ngay cả zsh cũng có một chế độ trong đó chủ yếu là tuân thủ POSIX.

Shell Bourne không tuân thủ POSIX và hiện không thể tìm thấy trên nhiều hệ thống. Trường hợp vỏ Bourne được tìm thấy hoặc không có vỏ, sẽ luôn có một "sh" tuân thủ POSIX (và sẽ không phải là vỏ Bourne), nói chung trong /binkhi một ngoại lệ đáng chú ý (gây phiền nhiễu) là Solaris.

Lưu ý rằng trước vỏ Bourne, và chúng ta đã nói chuyện hơn 30 năm trước, "sh" là vỏ của Thompson. Chúng tôi sẽ không viết các kịch bản tương thích với trình bao Thompson nữa. Tương tự như vậy, chúng ta nên ngừng nghĩ "sh" là vỏ Bourne.

Bây giờ "sh" là một đặc tả, không có nhiều biến thể đôi khi không tương thích của một triển khai. Điều đó làm cho nó dễ dàng hơn nhiều để viết các kịch bản di động. Chỉ cần làm theo các đặc điểm kỹ thuật .

Điều đó đúng với "sh" và tất cả các tiện ích tiêu chuẩn (sed, cut, tr ...)


+1 cho "ghi vào đặc tả." Nhưng đáng buồn là điều đó thường không đủ cho tính di động. Ví dụ, nếu người ta muốn sử dụng các mẫu kiểu egrep trong sed thì sao? Các đặc điểm kỹ thuật không cung cấp cho điều này. Trên các hệ thống có tiện ích dựa trên Gnu (hoặc BusyBox), bạn sử dụng sed -r. Trên các hệ thống có tiện ích dựa trên BSD, bạn sử dụng sed -E. SedBS của FreeBSD chấp nhận cả hai, nhưng Mac OS X chỉ chấp nhận -E. Và vân vân.
dubiousjim

Đó là bên cạnh quan điểm. Thông số kỹ thuật không cung cấp nó, vì vậy bạn không thể sử dụng nó một cách hợp lý / POSIXly. Nếu bạn sử dụng BREs, nó sẽ hoạt động trên tất cả các hệ thống tuân thủ POSIX, đó là sự đảm bảo được đưa ra bởi POSIX, đó là lý do tại sao nó hữu ích. Ngoài POSIX như bạn nói, không có hy vọng nào vì sed không hỗ trợ ERE hoặc hỗ trợ nó với một tùy chọn khác hoặc cú pháp ERE khác. Lưu ý rằng ERE có khả năng kém hơn BREs (chỉ cú pháp được mở rộng trong ERE để giúp bạn tiết kiệm một số thao tác gõ. ERE có thể được dịch sang BRE, điều ngược lại là không đúng (BRE \(...\)\1không có bản dịch trong ERE tiêu chuẩn).
Stéphane Chazelas

1
Tôi nhận ra rằng (POSIX) ERE thiếu phản hồi; thực tế tôi đã tham gia chỉnh sửa một phần của tiêu chuẩn. Điều đó không đúng khi các POSIX ERE có khả năng kém hơn BRE, vì trong tiêu chuẩn hiện tại, sự thay thế không được xác định cho BRE. Tuy nhiên, tôi không biết về bất kỳ công cụ regex nào không tôn vinh \|BREs. Tôi là tất cả để viết càng tốt càng tốt. Tôi chỉ thực hiện quan sát (tôi nghĩ được đánh giá cao) rằng điều này có thể gây đau đớn, và đôi khi viết thư cho POSIX đơn giản là không thể. Ở đâu đó có các liên kết thể hiện nhiều sai lầm như vậy; sẽ tìm kiếm chúng.
dubiousjim

điểm tốt về sự xen kẽ, tôi quên mất điều đó và đứng ra sửa chữa. Với sed, không có khả năng chặn mặc dù bạn có thể sử dụng một số biểu thức để khớp với các biểu thức thay thế. Có awk trong bộ công cụ tiêu chuẩn có thể được sử dụng nếu cần ERE. Tôi rất hiếm khi thấy mình theo công cụ tiêu chuẩn, và khi tôi làm, nói chung là trường hợp một ngôn ngữ khác như perl phù hợp hơn, nhưng tôi thấy quan điểm của bạn (mặc dù tôi vẫn nghĩ rằng bên cạnh chủ đề này về cách viết các tập lệnh di động)
Stéphane Chazelas

Một ví dụ tôi nghĩ về offhand: các dòng shebang (ở đầu mỗi tập lệnh shell) không được chỉ định trong POSIX. Ngoài ra, tôi không chắc chắn mình đã từng sử dụng một hệ thống tuân thủ 100% POSIX. Ví dụ: POSIX nói rằng bạn có thể bao gồm các dòng mới bên trong ${VAR:=stuff...here}nhưng nhiều vỏ không cho phép bạn, bạn phải đặt dấu ngoặc kép stuff...here.
dubiousjim
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.