Bash shebang ưa thích là gì?


1132

Có bất kỳ Bashshebang khách quan tốt hơn so với những người khác cho hầu hết các sử dụng?

  • #!/usr/bin/env bash
  • #!/bin/bash
  • #!/bin/sh
  • #!/bin/sh -
  • Vân vân

Tôi mơ hồ nhớ lại cách đây rất lâu khi nghe rằng việc thêm một dấu gạch ngang vào cuối sẽ ngăn ai đó truyền lệnh vào tập lệnh của bạn, nhưng không thể tìm thấy bất kỳ chi tiết nào về điều đó.


4
Và nó /usr/local/bin/bashtrên OpenBSD.
ngày

Câu trả lời:


1535

Bạn nên sử dụng #!/usr/bin/env bashcho tính di động : khác nhau * nixes đặt bashở những nơi khác nhau và sử dụng /usr/bin/envlà một cách giải quyết để chạy cái đầu tiên bashđược tìm thấy trên PATH. Và shkhông phảibash .


9
Cảm ơn. Cũng giống như thêm - vào cuối $! / Usr / bin / env bash - sẽ không làm gì cả vì chỉ có một đối số được * nix cho phép trong shebang và được sử dụng bởi 'bash'. Điều đó rõ ràng chỉ hữu ích trong việc ngăn chặn các đối số độc hại được chuyển đến tập lệnh trên dòng lệnh nếu shebang của tập lệnh là một trong những đối số khác không có đối số ( /bin/sh, v.v.).
Kurtosis

13
@Ray bashkhông sống /bintrên tất cả các hệ thống.
ptierno

12
Tương tự với tôi, tôi chỉ cần thêm nó vào một bí danh: alias shebang='echo "#!/usr/bin/env bash"'bây giờ tôi chỉ cần mở terminal và gõ shebang thay vì vào đây.
Oylex

19
Câu trả lời này là lừa dối. POSIX không nói rằng đó envlà tại /usr/bin/env. Nó có thể ở /bin/envhoặc bất cứ nơi nào trên thực tế, miễn là nó nằm trên đường dẫn. Nó có thể là /dummy/envnếu /dummylà trong PATH. Bản thân Shebang không được xác định trong POSIX, vì vậy tôi có thể #!stop toasterkhởi động máy pha cà phê USB và tuân thủ POSIX. Vì vậy, #!/usr/bin/env bashkhông phải là đặc biệt tốt hơn #!/bin/bash, nó có thể ít di động hơn.
darkfeline

19
@darkfeline Tính di động không tuyệt đối - về mặt toán học không thể thực hiện bất kỳ tập lệnh nào sẽ làm điều tương tự trên mọi nền tảng. Từ năm 2012 đến 2018 /usr/bin/envtồn tại trên nhiều máy hơn cả /bin/bashxor /usr/bin/bash, do đó, một kịch bản bắt đầu với dòng này sẽ thực hiện điều mong đợi trên càng nhiều máy càng tốt.
l0b0

80

/bin/shthường là một liên kết đến hệ vỏ mặc định của hệ thống, thường là bashvậy, ví dụ, các hệ thống Debian có trọng lượng nhẹ hơn dash. Dù bằng cách nào, vỏ Bourne ban đầu là shvậy, vì vậy nếu tập lệnh của bạn sử dụng một số bashtính năng cụ thể (thế hệ thứ 2, "Bourne Again sh") ( [[ ]]kiểm tra, mảng, nhiều thứ có đường, v.v.), thì bạn nên cụ thể hơn và sử dụng sau . Bằng cách này, trên các hệ thống không cài đặt bash, tập lệnh của bạn sẽ không chạy. Tôi hiểu có thể có một bộ ba phim thú vị về sự tiến hóa này ... nhưng đó có thể là tin đồn.

Cũng lưu ý rằng khi được gợi lên sh, bashở một mức độ nào đó sẽ hoạt động như tiêu chuẩn POSIX sh (xem thêm các tài liệu GNU về điều này).


2
Public Korn Shell (pdksh) được mặc định trên OpenBSD.
ngày

Hầu hết các hệ thống sẽ không liên kết /bin/shđến bất cứ nơi nào /usrvì điều đó sẽ khiến cho các script init chạy khó hơn trước khi /usrđược gắn kết.
aij

@aij Tôi không biết lý do tại sao tôi đặt "nhiều hoặc nhiều nhất" ở đó - Tôi là người dùng fedora, ở đó /bin/sbintrong nhiều năm chỉ là các liên kết tượng trưng theo mặc định, /usr/bin/usr/sbintrong bối cảnh đó /bin/shlà một liên kết đến bashvà thực tế thư mục là /usr/bin. Nhưng tôi sẽ sửa những điều trên.
tinh

44

Tôi khuyên bạn nên sử dụng:

#!/bin/bash

Nó không phải là 100% di động (một số hệ thống đặt bashở một vị trí khác /bin), nhưng thực tế là rất nhiều tập lệnh hiện có sử dụng #!/bin/basháp lực các hệ điều hành khác nhau để tạo ra /bin/bashít nhất một liên kết tượng trưng đến vị trí chính.

Sự thay thế của:

#!/usr/bin/env bash

đã được đề xuất - nhưng không có gì đảm bảo rằng envlệnh được đưa vào /usr/bin(và tôi đã sử dụng các hệ thống không có). Hơn nữa, biểu mẫu này sẽ sử dụng phiên bản đầu tiên của bashngười dùng hiện tại $PATH, đây có thể không phải là phiên bản phù hợp của bash shell.

(Nhưng /usr/bin/envnên hoạt động trên bất kỳ hệ thống hiện đại hợp lý nào, vì envlà trong /usr/binhoặc vì hệ thống làm gì đó để nó hoạt động. Hệ thống tôi đã đề cập ở trên là SunOS 4, có lẽ tôi đã không sử dụng trong khoảng 25 năm.)

Nếu bạn cần một tập lệnh để chạy trên một hệ thống không có /bin/bash, bạn có thể sửa đổi tập lệnh để trỏ đến vị trí chính xác (điều đó thừa nhận là bất tiện).

Tôi đã thảo luận về sự đánh đổi sâu hơn trong câu trả lời của tôi cho câu hỏi này .

Một bản cập nhật hơi khó hiểu: Một hệ thống tôi sử dụng, Termux , một lớp giống như máy tính để bàn chạy trên Android, không có /bin/bash( bash/data/data/com.termux/files/usr/bin/bash) - nhưng nó có xử lý đặc biệt để hỗ trợ #!/bin/bash.


3
2 năm sau và đây vẫn là lời khuyên tốt nhất ở đây. Nếu giải pháp đơn giản không hiệu quả thì bạn phải đặt câu hỏi cho các quyết định trước đó của mình. Câu trả lời được chấp nhận và được đánh giá cao nhất không sai, chỉ là không đúng :)
Kỹ sư phần mềm

27

Sử dụng một dòng shebang để gọi trình thông dịch phù hợp không chỉ dành cho BASH. Bạn có thể sử dụng shebang cho bất kỳ ngôn ngữ được dịch nào trên hệ thống của bạn như Perl, Python, PHP (CLI) và nhiều ngôn ngữ khác. Nhân tiện, shebang

#!/bin/sh -

(cũng có thể là hai dấu gạch ngang, tức là --) kết thúc các tùy chọn bash mọi thứ sau đó sẽ được coi là tên tệp và đối số.

Sử dụng envlệnh làm cho tập lệnh của bạn có thể di động và cho phép bạn thiết lập môi trường tùy chỉnh cho tập lệnh của mình do đó tập lệnh di động nên sử dụng

#!/usr/bin/env bash

Hoặc cho bất cứ ngôn ngữ nào như đối với Perl

#!/usr/bin/env perl

Hãy chắc chắn để nhìn vào man trang cho bash:

man bash

env:

man env

Lưu ý: Trên các hệ thống dựa trên Debian và Debian, như Ubuntu, sh được liên kết đến dashkhông bash. Như tất cả các kịch bản hệ thống sử dụng sh. Điều này cho phép bash phát triển và hệ thống ổn định, theo Debian.

Ngoài ra, để giữ lời gọi * nix như tôi không bao giờ sử dụng tiện ích mở rộng tệp trên shebang đã gọi các tập lệnh, vì bạn không thể bỏ qua tiện ích mở rộng trên lệnh gọi trên các tệp thực thi như bạn có thể trên Windows. Lệnh tập tin có thể xác định nó là một tập lệnh.


4

Nó thực sự phụ thuộc vào cách bạn viết các tập lệnh bash của bạn. Nếu bạn /bin/shđược liên kết với bash, khi bash được gọi là sh, một số tính năng không khả dụng .

Nếu bạn muốn các tính năng không dành riêng cho bash, không phải POSIX, hãy sử dụng #!/bin/bash


3
Bash không được cài đặt trên OpenBSD. Nếu bạn cài đặt nó thông qua pkg_add, thì nó nằm ở /usr/local/binđó, có thể không có trên đường dẫn.
ngày

làm thế nào về một POSIXtính năng?
Nikolan Asad
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.