Chạy tập lệnh bash thực thi có dấu gạch chéo hoặc không


2

Tôi có bash script test.shkhông có gì đặc biệt:

#!/bin/bash
echo Hello!

Nếu tôi chạy nó như thế này . test.sh, nó hoạt động.

kopparberg:dev marek$ . test.sh
Hello!

Nếu tôi chạy nó như thế này ./test.shthì không được.

kopparberg:dev marek$ ./test.sh 
-bash: ./test.sh: /bin/bash^M: bad interpreter: No such file or directory

Sự khác biệt là gì?

Câu trả lời:


5

Sự khác biệt giữa tìm nguồn ( . test.sh) tập lệnh và chạy tập lệnh ( test.shhoặc ./test.sh) nằm ở dòng đầu tiên.

Nếu bạn nguồn kịch bản, dòng đầu tiên chỉ là một nhận xét và bỏ qua. Nhưng nếu bạn chạy nó, dòng đầu tiên được kiểm tra bởi kernel cho hai ký tự đầu tiên và nếu chúng là " #!", phần còn lại của dòng sẽ được sử dụng làm đường dẫn và đối số đầu tiên cho trình thông dịch. Đó là kernel sẽ tìm kiếm một tệp thực thi có tên /bin/bashvà truyền cho nó tên của kịch bản làm đối số đầu tiên. Như thế này : /bin/bash ./test.sh.

Đây là những gì thường xảy ra và bạn đã đúng, nó sẽ có tác dụng tương tự cho kịch bản của bạn. Nhưng tập lệnh của bạn chứa một vấn đề: Dòng đầu tiên kết thúc bằng dòng kết thúc DOS (CR LF) thay vì kết thúc dòng unix (LF). Vì vậy, tên của trình thông dịch, như kernel thấy nó /bin/bash^Mkhông tồn tại trên đĩa của bạn (^ M là viết tắt của CR giả trước khi dòng kết thúc). Để làm cho vấn đề tồi tệ hơn, nhân vật ^ M thường vô hình.

Bạn có thể chứng minh rằng đây là trường hợp với cat -v test.sh(in thay thế ^ M cho ký tự CR vô hình).


2

Giải pháp nắm tay là một bí danh cho lệnh "nguồn".

Các shebang được coi như một #comment cho nguồn

Khi bạn gọi tập lệnh với ./script, trình bao sẽ thực thi tập lệnh với shebang #!/bin/bash

Lỗi bạn đưa ra dường như là sự cố CRLF, bạn có thể chạy:

dos2unix script.sh

để loại bỏ các dòng cuối Windows.

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.