Câu hỏi Sự khác nhau giữa #! / Bin / sh và #! / Bin / bash là gì?


nếu tôi viết,

#!/bin/bash
echo "foo"

hoặc là

#!/bin/sh
echo "foo"

cả hai sản lượng giống nhau. Tôi đã thấy một số tập lệnh bắt đầu bằng #!/bin/sh hoặc là #!/bin/bash. Có sự khác biệt nào giữa chúng không?


211
2018-05-25 03:59


gốc




Các câu trả lời:


bash và sh là hai vỏ khác nhau. Về cơ bản bash Là sh, với nhiều tính năng hơn và cú pháp tốt hơn. Hầu hết các lệnh làm việc giống nhau, nhưng chúng khác nhau.

Có nói rằng, bạn nên nhận ra /bin/sh trên hầu hết các hệ thống sẽ là một liên kết tượng trưng và sẽ không gọi sh. Trong Ubuntu /bin/sh được sử dụng để liên kết đến bash, hành vi điển hình trên bản phân phối Linux, nhưng bây giờ đã thay đổi để liên kết tới một vỏ khác gọi là gạch ngang. tôi sẽ dùng bash, vì đó là khá nhiều tiêu chuẩn (hoặc ít nhất là phổ biến nhất, từ kinh nghiệm của tôi). Thực tế, các vấn đề phát sinh khi một tập lệnh bash sẽ sử dụng #!/bin/sh bởi vì trình tạo tập lệnh giả định liên kết là bash khi nó không phải là.

Để biết thêm thông tin, http://man.cx/sh, http://man.cx/bash.


178
2018-05-25 04:08



Đoạn đầu tiên của bạn khá là gây hiểu nhầm. "sh" không phải là một trình bao nào cả, nhưng một liên kết tượng trưng đến cấu hình hiện được cấu hình vỏ hệ thống, mà trên các hệ thống Linux thường hoặc là bash hoặc dấu gạch ngang (các phiên bản gần đây của Ubuntu bằng cách sử dụng sau này). - thomasrutter
/bin/sh từng là một cái vỏ gọi là vỏ bourne vào năm 1977. bash là một vỏ tương thích / bin / sh có thể được sử dụng như là một thay thế vỏ bourne đó là posix phù hợp. en.wikipedia.org/wiki/Bourne_shell - Alex
bash là một chuẩn thực tế (được sử dụng rất rộng rãi) nhưng nó không phải là "chuẩn"; sh trên Ubuntu sử dụng dấu gạch ngang, đó là một vỏ tuân thủ Posix, vì vậy nó thực sự là tiêu chuẩn. Lời khuyên của tôi là sử dụng dấu gạch ngang càng thường xuyên càng tốt cho tập lệnh, đặc biệt là đối với tập lệnh phía máy chủ. Mặc dầu bashmang tính biểu cảm hơn, dấu gạch ngang chạy nhanh hơn rất nhiều và an toàn hơn. - Rick-777
@ Rick-777 Vì vậy, tôi nên đặt một cách rõ ràng #! / Bin / dash ở đầu tập lệnh của tôi? Tôi cũng đã viết kịch bản mà tôi chỉ viết lệnh và thực hiện với ./scriptName và điều đó đã làm việc tốt. #! / Bin / yourShellHere có cần thiết không? - user137717
@ Rick-777 Trong trường hợp tôi loại trừ bất kỳ #! / Bin / shellName nào, tôi đã đặt tên tệp là fileName.sh. Nó sẽ liên kết hoàn toàn với hệ vỏ ưa thích mà không khai báo #! / Bin / sh? - user137717


Trên Linux và các hệ thống giống Unix khác, bạn có nhiều lựa chọn.

Shell không chỉ chịu trách nhiệm cho việc vẽ dấu nhắc nhỏ của bạn, mà còn giải thích các lệnh của bạn, đặc biệt nếu bạn đặt vào logic phức tạp như các đường ống, các điều kiện và vân vân.

bash là trình bao phổ biến nhất được sử dụng làm trình bao mặc định cho người dùng hệ thống Linux. Nó là một hậu duệ tinh thần của các vỏ khác được sử dụng trong suốt lịch sử Unix. Tên của nó, bash là một từ viết tắt của Bourne-Again Shell, một sự tôn kính với vỏ Bourne nó được thiết kế để thay thế, mặc dù nó cũng kết hợp các tính năng từ C Shell và Korn Shell.

Nó chạy, những ngày này, từ /bin/bash - bất kỳ hệ thống nào có bash sẽ có thể truy cập ở đây.

Nó không chỉ là người dùng sử dụng shell. Kịch bản (shell script) cần vỏ để giải thích chúng. Khi bạn chạy một kịch bản lệnh shell, hệ thống của bạn cần khởi động một quá trình shell để thực thi kịch bản lệnh của bạn.

Vấn đề là, các shell khác nhau có sự mâu thuẫn nhỏ giữa chúng, và khi nói đến các script chạy, đây có thể là một vấn đề thực sự. bash có khá nhiều tính năng tạo kịch bản chỉ có duy nhất để bash chứ không phải các shell khác. Điều này là tốt, nếu bạn luôn sử dụng bash để chạy các script đó. Các shell khác có thể thử giả lập bash, hoặc tuân thủ tiêu chuẩn POSIX, bash hỗ trợ khá tốt (mặc dù thêm phần mở rộng của nó vào).

Có thể chỉ định ở trên cùng của một kịch bản lệnh shell mà nó sẽ được chạy bằng cách sử dụng một shebang. Tập lệnh có thể chỉ định #!/bin/bash trên dòng đầu tiên, có nghĩa là tập lệnh phải luôn được chạy bằng bash chứ không phải là một trình bao khác.

/ bin / sh là một tệp thực thi đại diện cho vỏ hệ thống. Trên thực tế, nó thường được thực hiện như là một liên kết tượng trưng trỏ đến tệp thực thi cho bất kỳ trình bao nào là hệ vỏ. Vỏ hệ thống là loại vỏ mặc định mà tập lệnh hệ thống nên sử dụng. Trong các bản phân phối Linux, trong một thời gian dài, đây thường là một liên kết tượng trưng đến bash, rất nhiều để nó đã trở thành một phần của quy ước để luôn liên kết / bin / sh để bash hoặc bash-tương thích với trình bao. Tuy nhiên, trong vài năm qua Debian (và Ubuntu) đã quyết định chuyển vỏ hệ thống từ bash sang dấu gạch ngang - một vỏ tương tự - phá vỡ với một truyền thống lâu đời trong Linux (tốt, GNU) của việc sử dụng bash cho / bin / sh. Dấu gạch ngang được xem là vỏ nhẹ hơn và nhanh hơn nhiều, có thể mang lại lợi ích cho tốc độ khởi động (và những thứ khác đòi hỏi nhiều kịch bản lệnh shell, như các kịch bản cài đặt gói).

Dash khá tương thích với bash, dựa trên cùng một tiêu chuẩn POSIX. Tuy nhiên, nó không thực hiện các phần mở rộng bash cụ thể. Có các kịch bản tồn tại sử dụng #!/bin/sh (hệ vỏ) là trục trặc của chúng, nhưng yêu cầu phần mở rộng bash cụ thể. Điều này hiện được coi là lỗi cần được sửa bởi Debian và Ubuntu, những người yêu cầu / bin / sh để có thể làm việc khi chỉ vào dấu gạch ngang.

Mặc dù Ubuntu vỏ hệ thống đang trỏ đến dấu gạch ngang, đăng nhập shell khi người dùng tiếp tục bị bash vào lúc này. Tức là, khi bạn đăng nhập vào trình giả lập thiết bị đầu cuối ở bất kỳ đâu trong Linux, shell đăng nhập của bạn sẽ bị bash. Tốc độ hoạt động không phải là quá nhiều vấn đề khi trình bao được sử dụng tương tác, và người dùng quen thuộc với bash (và có thể có các tùy chỉnh cụ thể bash trong thư mục chính của họ).

Những gì bạn nên sử dụng khi viết kịch bản

Nếu tập lệnh của bạn yêu cầu các tính năng chỉ được bash hỗ trợ, hãy sử dụng #!/bin/bash.

Nhưng nếu có thể, tốt nhất là đảm bảo tập lệnh của bạn tương thích với POSIX và sử dụng #!/bin/sh, nên luôn luôn, khá đáng tin cậy, trỏ đến hệ thống tương thích POSIX được ưa thích trong bất kỳ cài đặt nào.


62
2018-05-25 08:31





Ngoài các câu trả lời trước, ngay cả khi /bin/sh là một liên kết tượng trưng đến /bin/bash, #!/bin/sh không hoàn toàn tương đương với #!/bin/bash.

Từ bash (1) trang người đàn ông :

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

Ví dụ: cú pháp cụ thể bash:

 exec  > >(tee logfile.txt)

đưa ra lỗi trong một trình bao bắt đầu bằng #!/bin/sh, ngay cả với liên kết tượng trưng bash tại chỗ.


15
2018-01-14 11:24