Các tập lệnh của bạn có thể có các kết thúc dòng CR-LF theo phong cách DOS và không phải là các kết thúc dòng LF theo phong cách Unix. ^ M thấy trong thông báo lỗi trong trường hợp đầu tiên là dấu hiệu cho thấy ký tự 0D được hiểu là một phần của tên trình thông dịch kịch bản và không phải là một phần của dòng kết thúc (như người ta có thể mong đợi). Vì không có tệp thực thi trên hệ thống của bạn với đường dẫn bao gồm ký tự 0D (^ M), nên hệ thống không thể gọi trình thông dịch. Khi bạn gọi thủ công trình thông dịch của mình, nó có thể xử lý cả hai loại kết thúc dòng có trong tập lệnh.
Nếu bạn chuyển đổi các tập lệnh để sử dụng các kết thúc dòng LF theo phong cách Unix, bạn sẽ thấy shebang hoạt động. Đọc để minh họa.
Trong phiên bên dưới, todos và fromdos là một tiện ích (có sẵn trên Ubuntu dưới dạng gói tofrodos
) để chuyển đổi các quy ước kết thúc dòng từ CR-LF sang LF. Bất kỳ tiện ích tương đương nào (xem câu hỏi unix.SE này ) sẽ làm cho mục đích trình diễn.
Bản ghi phiên sau (được thực hiện với cùng tệp tệp của bạn) sẽ làm rõ tình huống:
$ fromdos hello.sh
$ ./hello.sh
Hello
$ todos hello.sh
$ ./hello.sh
bash: ./hello.sh: /bin/sh^M: bad interpreter: No such file or directory
$
$ fromdos hello.py
$ ./hello.py
Hello
$ todos hello.py
$ ./hello.py
: No such file or directory
$
Có vẻ như đó là hạt nhân đọc dòng shebang và rõ ràng là nhân Linux (ít nhất là phiên bản trên hệ thống Kubfox Saucy của tôi) không nhận ra CR là một phần của quy ước kết thúc dòng CR-LF.
Nếu shebang của tập lệnh của bạn dường như không hoạt động (tức là gọi thủ công trình thông dịch trên tập lệnh hoạt động nhưng bạn không thể thực thi tập lệnh bằng tên tệp của tập tin mặc dù bạn đã thực hiện chmod +x
trên tập lệnh đó) thì đây là một lý do có thể.
LƯU Ý:
Cảm ơn những người khác đã bình luận quá. Tôi cũng rất vui khi biết nếu có câu trả lời tốt hơn!