Sự khác biệt giữa bash và sh là gì?


28

Tôi thấy hai loại mã đang được sử dụng:

#!/usr/bin/sh

và:

#!/user/bin/bash

Tôi đã tìm kiếm trực tuyến này và ý kiến ​​khác nhau rất nhiều. Những lời giải thích tôi thấy trên hầu hết các trang web đều nói rằng shnó cũ hơn bashvà không có sự khác biệt thực sự.

Có ai biết sự khác biệt giữa những điều này? Bạn có thể cho tôi một ví dụ thực tế khi sử dụng cái này hơn cái kia không?


để có cái nhìn tổng quan về các loại vỏ khác nhau (không chỉ shbash): http://en.wikipedia.org/wiki/Comparison_of_command_shells
akira

1
Một lịch sử tuyệt vời khác ở đây: faqs.org/faqs/unix-faq/shell/shell-differences
John Wright

Câu trả lời:


34

bashlà một superset của shtức là. tất cả mọi thứ bạn có thể làm trong shbạn có thể làm trong bash.

Bash có nhiều tính năng hơn (phân nhánh, dựng sẵn, mảng) làm cho tập lệnh dễ viết hơn. Một số sau * nix'es có /bin/shliên kết đến/bin/bash

Để được giải thích đầy đủ về những gì đây là một hướng dẫn


5
@Saif Bechan: Một lý do khiến vỏ Bourne ( sh) không chỉ được mở rộng là Bash` được viết bởi người khác. Ngoài ra tôi cá là có vấn đề về giấy phép. Đọc bài viết về Bourne Shell en.wikipedia.org/wiki/Bourne_shell
Felix

7
Việc xóa shsẽ phá vỡ rất nhiều tập lệnh mà nó mong đợi nó sẽ ở đó và dựa vào cách nó phân tích cú pháp. Người dùng Linux có thể không quan tâm, nhưng mọi người chi hàng ngàn đô la cho Solaris, AIX hoặc HP-UX có thể rất khó chịu.
njd

3
... Và để vui hơn nữa, các liên kết / bin / sh của Ubuntu sẽ xuất hiện. Dash không hoàn toàn tuân thủ sh hoặc bash, nhưng được cho là khởi động nhanh hơn. Khi hệ thống khởi động, tất cả các tập lệnh init.d chạy và tôi đoán rằng thời gian lưu tổng thể là xứng đáng.
kbyrd

8
Tôi khá chắc chắn Dash hoàn toàn tuân thủ sh. Vấn đề là một số người viết các tập lệnh nói / bin / sh, nhưng bản thân tập lệnh yêu cầu / bin / bash hoạt động. Không ai nhận thấy một vấn đề, bởi vì hầu hết thời gian, / bin / sh chỉ đơn giản chỉ vào / bin / bash.
davr

8
@Saif: Có một lý do khác khiến shnó không được mở rộng đơn giản: Mã nguồn của nó là địa ngục thuần túy. Hãy xem. được coi là C ...
grawity 21/03

6

Theo truyền thống, / bin / sh sẽ là shell Bourne ban đầu, không có lịch sử hoặc chỉnh sửa dòng lệnh và không có kiểm soát công việc.

Trong khoảng 15 năm trở lại đây, hầu hết các Unix đã cài đặt shell POSIX, hoặc ít nhất là ksh hoặc bash (rất giống với POSIX), nhưng vẫn có shell / bin / sh hạn chế hơn

Lý do cho điều đó là để các kịch bản shell cũ hơn mong đợi shlệnh cũ hơn vẫn hoạt động.
Kể từ khi nhân vật thích {, }!có ý nghĩa đặc biệt để bash, nó có thể là một kịch bản vỏ cũ bằng những ký tự (không thoát họ) có thể thất bại.
(Shell Bourne sẽ có !!{1,2}nghĩa đen, trong khi bash sẽ diễn giải điều đó như là sự lặp lại của lệnh trước đó ( !!) theo sau là mở rộng cú đúp).

Trên Linux, shlệnh hầu như luôn luôn là một liên kết đến bash, với tất cả các tính năng tương tự.


2
Bash được cho là (nhưng không phải luôn luôn) hoạt động trong chế độ tương thích sh nếu được gọi là / bin / sh. Rất nhiều thứ đã bị hỏng khi Ubuntu chuyển / bin / sh từ liên kết đến / bin / bash sang liên kết đến / bin / dash. Những thứ đã phá vỡ bashism giả khi họ nên sử dụng sh tiêu chuẩn.
Broam

4

sh có thể có nghĩa là vỏ Bourne hoặc / bin / sh, là một số vỏ khác (phù hợp với POSIX) trên hầu hết các nền tảng hiện đại. "Shell POSIX" là shell trừu tượng được xác định bởi POSIX , được triển khai bằng bash ở chế độ POSIX hoặc ksh hoặc dash theo mặc định. / bin / sh đôi khi cũng được gọi là vỏ POSIX, vì đó là vỏ phù hợp với POSIX trên hầu hết các nền tảng. Các vỏ Bourne ban đầu không phải là vỏ POSIX.

bashref có một danh sách các khác biệt giữa bash và Bourne shell . man bashcó một danh sách các thay đổi khi bash được gọi trong chế độ POSIX .

/ bin / sh không phải là liên kết tượng trưng hoặc liên kết cứng trên OS X, nhưng nó có cùng kích thước với / bin / bash:

$ ls -li /bin/{ba,}sh
29631757 -r-xr-xr-x  1 root  wheel  1333920 Jul 26 01:52 /bin/bash
29631758 -r-xr-xr-x  1 root  wheel  1334000 Jul 26 01:52 /bin/sh

người đàn ông bash :

Nếu bash được gọi với tên sh, nó sẽ cố gắng bắt chước hành vi khởi động của các phiên bản lịch sử của sh càng gần càng tốt, đồng thời tuân thủ tiêu chuẩn POSIX.

Việc bắt chước của vỏ Bourne là khá hạn chế. bash +B(Bourne) thực sự sẽ vô hiệu hóa các tính năng như mở rộng cú đúp.

$ sh
$ echo {a,b}
a b
$ echo $BASH_VERSION
3.2.48(1)-release
$ bash +B
$ echo {a,b}
{a,b}

Nhưng ngay cả khi bạn tắt chế độ POSIX, echo vẫn hoạt động như echo -emặc định:

$ sh
$ shopt -uo posix
$ echo '1\b2'
2

/ bin / sh là dấu gạch ngang trên Ubuntu , vì vậy một số bashism hoạt động với / bin / sh trên OS X nhưng không phải Ubuntu.

Nếu bạn thực sự muốn viết các kịch bản cho (giống như) các vỏ Bourne ban đầu, bạn có thể sử dụng #!/usr/bin/env bash +Bthay thế.

Tôi nghĩ việc viết tập lệnh cho bash dễ dàng hơn là tránh các tính năng không phải là một phần của thông số kỹ thuật POSIX hoặc shell Bourne hoặc kiểm tra mọi thứ với các shell khác.


2

Trên thực tế, mặc dù / bin / sh có thể là một liên kết đến / bin / bash, nếu được khởi động như sh, nó hoạt động khác đi. Từ trang bash:

Nếu bash được gọi với tên sh, nó sẽ cố gắng bắt chước hành vi khởi động của các phiên bản lịch sử của sh càng gần càng tốt, đồng thời tuân thủ tiêu chuẩn POSIX.

Vì vậy sh, nó cố gắng mô phỏng hành vi sh lịch sử. Vì bash, nó cố gắng trở nên hữu ích nhất có thể như một vỏ đăng nhập tương tác.


2

Trên nhiều hệ thống và trên Solaris nói riêng, bash được liên kết động trong khi sh được liên kết tĩnh. Điều này có thể gây ra mối đe dọa bảo mật, vì lý do này, người dùng root chỉ nên sử dụng / bin / sh làm shell (nếu bạn cần đăng nhập với quyền root).


2
Cũng có thể hữu ích trong trường hợp khẩn cấp nếu bạn làm điều gì đó xấu với ldconfighoặc /libthư mục của bạn bị xóa sổ vì một số lý do.
LawrenceC
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.