Shell nào thực thi các tập lệnh khi không có dòng shebang (#! / Path / to / shell) ở đầu? Tôi giả sử / bin / sh nhưng tôi không thể xác nhận.
Hạt nhân từ chối thực hiện kịch bản và lợi nhuận như vậy ENOEXEC, vì vậy hành vi chính xác phụ thuộc vào chương trình bạn chạy một kịch bản như vậy từ .
- bash 4.2.39 - sử dụng chính nó
- busybox-ash 1.20.2 - sử dụng chính nó
- dấu gạch ngang 0,5,7 - lượt chạy / thùng / sh
- cá 1.23.1 - phàn nàn về ENOEXEC, sau đó đổ lỗi cho tệp sai
- AT & T ksh 93u + 2012.08.01 - sử dụng chính nó
- mksh R40f - chạy / bin / sh
- pdksh 5.2,14 - chạy / bin / sh
- sh-heirloom 050706 - sử dụng chính nó
- tcsh 6.18.01 - chạy / bin / sh
- zsh 5.0.0 - chạy / bin / sh
- cmd.exe 5.1.2600 - nhìn bạn buồn cười.
Trong glibc , các chức năng execv()
hoặc execve()
chỉ trả về ENOEXEC. Nhưng execvp()
ẩn mã lỗi này và tự động gọi / bin / sh. (Điều này được ghi lại trong exec (3p) .)
Điều gì được coi là "thực tiễn tốt nhất" về mặt viết kịch bản shell sẽ chạy trên bất kỳ nền tảng nào? (ok, đây là loại kết thúc mở)
Chỉ dính vào sh
và chỉ các tính năng do POSIX xác định hoặc chỉ cần sử dụng bash đầy đủ (có sẵn rộng rãi) và đề cập đến nó trong các yêu cầu của bạn nếu phân phối nó.
(Bây giờ tôi nghĩ về nó, Perl - hoặc có lẽ là Python - thậm chí còn dễ mang theo hơn, chưa kể đến việc có một cú pháp tốt hơn.)
Luôn luôn thêm dòng shebang. Nếu sử dụng bash hoặc zsh, hãy sử dụng #!/usr/bin/env bash
thay vì mã hóa đường dẫn của shell. (Tuy nhiên, vỏ POSIX được đảm bảo là có /bin/sh
, vì vậy bỏ qua env
trong trường hợp đó.)
(Thật không may, thậm chí /bin/sh
không phải lúc nào cũng giống nhau. Chương trình autoconf GNU phải đối phó với nhiều quirks khác nhau .)
Có thể viết một tập lệnh cố gắng sử dụng zsh và quay lại bash nếu zsh không có sẵn? Tôi đã thử đặt hai dòng shebang, như bên dưới, nhưng nó chỉ gặp lỗi với trình thông dịch xấu: / bin / zsh: không có tệp hoặc thư mục nào như vậy nếu tôi thử nó trên máy không có zsh.
Chỉ có thể có một dòng shebang; mọi thứ sau ký tự dòng mới thậm chí không được đọc bởi kernel và được coi là một nhận xét bằng shell.
Có thể viết một tập lệnh chạy dưới dạng #!/bin/sh
, kiểm tra xem shell nào có sẵn và chạy exec zsh "$0" "$@"
hoặc exec bash "$0" "$@"
tùy thuộc vào kết quả. Tuy nhiên, cú pháp được sử dụng bởi bash và zsh rất khác nhau ở những nơi khác nhau mà tôi không khuyên bạn nên làm điều này vì sự tỉnh táo của riêng bạn.