Nói chung, chúng ta hãy xem xét một tập tin testcode
với mã bash trong đó
bạn có thể làm ba việc khác nhau với nó:
$ ./testcode
You are executing ./testcode
này hoạt động nếu testcode có đủ quyền hạn và đúng shebang. Với một shebang của #!/bin/false
, kết quả này không có gì và trả về mã 1 (sai).
$ bash ./testcode
You are executing ./testcode
Điều này hoàn toàn bỏ qua shebang (thậm chí có thể bị thiếu) và chỉ yêu cầu quyền đọc, không được phép thực thi. Đây là cách để gọi các script bash từ một dòng lệnh CMD trong Windows (nếu bạn có bash.exe
trong PATH của bạn ...), vì ở đó, machanism của shebang không hoạt động.
$ . ./testcode
You are sourcing ./testcode
này cũng hoàn toàn không quan tâm đến các công việc, như ở trên, nhưng nó là một vấn đề hoàn toàn khác nhau, vì nguồn một kịch bản nghĩa có vỏ hiện thực nó, trong khi thực hiện một kịch bản nghĩa cách gọi một trình bao mới để thực thi nó. Ví dụ: nếu bạn đặt lệnh exit
trong tập lệnh có nguồn gốc, bạn thoát khỏi trình bao hiện tại, điều này hiếm khi bạn muốn. Do đó, tìm nguồn cung ứng thường được sử dụng để tải các định nghĩa hàm hoặc hằng số, theo cách tương tự như câu lệnh import
của các ngôn ngữ lập trình khác và các lập trình viên khác nhau phát triển các thói quen khác nhau giữa các tập lệnh được thực thi và bao gồm các tệp. Tôi thường không sử dụng bất kỳ tiện ích nào cho tiện ích mở rộng cũ (những người khác sử dụng .sh
), nhưng tôi sử dụng một phần mở rộng là .shinc
cho phần sau. Đồng nghiệp cũ của bạn đã sử dụng một shebang của #!/bin/false
và người ta chỉ có thể hỏi họ tại sao họ lại ưa thích điều này với hàng triệu khả năng khác. Một lý do mà nói đến cái tâm của tôi là bạn có thể sử dụng file
nói với những tập tin ngoài:
$ file testcode testcode2
testcode: Bourne-Again shell script, ASCII text executable
testcode2: a /bin/false script, ASCII text executable
Tất nhiên, nếu bao gồm các file chỉ chứa các định nghĩa chức năng, đó là vô hại để thực hiện chúng, vì vậy tôi không nghĩ rằng đồng nghiệp của bạn đã làm nó để ngăn chặn thực hiện.
Một thói quen của tôi, lấy cảm hứng từ thế giới Python, là đặt một số xét nghiệm hồi quy ở phần cuối của .shinc
tác phẩm của tôi (ít nhất là trong khi phát triển)
... function definitions here ...
[ "$0" != "${BASH_SOURCE[0]}" ] && return
... regression tests here ...
Kể từ return
tạo ra một lỗi trong kịch bản thực hiện nhưng OK trong các tập lệnh có nguồn gốc, một cách khó hiểu hơn để có được kết quả tương tự là
... function definitions here ...
return 2>/dev/null || :
... regression tests here ...
Bạn đã tự nói: với nội dung «false', nội dung không được thực thi. Đó là một sự an toàn, trong trường hợp kịch bản là dễ bị lỗi khi được sử dụng trong bối cảnh sai hoặc ressource nặng. Rất có thể, đó là thói quen mà đồng nghiệp của bạn đã chọn, điều đó không ảnh hưởng đến mã trong hầu hết các trường hợp nhưng điều đó có thể hữu ích trong những trường hợp phức tạp hơn. – Aserre
Cũng cần lưu ý rằng, dòng she-bang '#!/Bin/true' hoặc' #!/Bin/false' không ảnh hưởng đến kịch bản khi bạn gọi trình thông dịch shell trực tiếp dưới dạng 'bash my_script.sh ', cú pháp này chạy script với' bash' không có vấn đề gì và lặp lại đầu ra 'foontastic' – Inian
'./my_bar.sh' không sinh ra một subshell: nó sinh ra một shell hoàn toàn mới. Đây không chỉ là một kỹ thuật: subshells nhận được một bản sao của tất cả các biến của shell chính (bao gồm cả các biến không được đánh dấu để export), trong khi một shell riêng chỉ nhận các biến được export. Subshells được khởi chạy theo các cách khác, ví dụ bằng cách đặt dấu ngoặc kép '()', bắt đầu các đường dẫn '|', quá trình/thay thế lệnh '$()' '<()' '>()'. – Fred