Tại sao các cô ấy lại bắt đầu với một trò chơi #!


10

Tại sao "cô ấy" lại bắt đầu bằng một #!, như thế #!/bin/bashnào? Tôi đã luôn chấp nhận rằng nó được thực hiện như thế nào, nhưng có một lý do đằng sau nó?

Tại sao bắt đầu với #; không phải đó thường là một bình luận? Hay đó là điểm mà nó nên được bình luận?


4
Wikipedia có một lịch sử khá chi tiết về #!(nhiều như dmr nhớ về), bao gồm cả lời giải thích tại sao #(vâng, dòng này phải bị bỏ qua bởi các shell hiện có).
Gilles 'SO- ngừng trở nên xấu xa'

Bỏ lỡ để kiểm tra wikipedia :)
Johan

1
Tôi chỉ ước đạn pháo đủ thông minh để loại bỏ CR / LF ngoại lai nếu nó ở đó ...;)
Aaron D. Marasco

Câu trả lời:


16

Thông thường shebang chỉ nói đến #!( !thường được gọi là "bang" và có vẻ như "cô ấy" là một tham nhũng của "SHArp" hoặc "haSH" cho #) - toàn bộ dòng được gọi là dòng shebang

Nó cố tình bắt đầu bằng một ký tự nhận xét để tương thích ngược với những thứ không biết cách xử lý nó; những !là có lẽ chỉ để phân biệt nó với một lời nhận xét ngẫu nhiên bắt đầu từ tập tin, do đó, một tập tin bắt đầu với # this is my script!không cố gắng để chạy các this is my script!phiên dịch


2
Bang !thường được sử dụng trong các bối cảnh khác để chỉ ra một lệnh sẽ được thực thi. Ví dụ trong vimhoặc các chương trình khác có dòng lệnh riêng, bang thường là ký tự thoát khiến chúng chạy lệnh trong hệ thống thay vì giao diện bên trong.
Caleb

4

Để hiểu điều này, bạn phải nhận ra rằng dòng đầu tiên của tập lệnh thực sự được đọc hai lần , bởi 2 chương trình khác nhau. Lần đầu tiên, kernel mở tệp và tìm chuỗi ký tự đó ( #!) trên dòng đầu tiên. Nếu nó tìm thấy nó, nó chạy chương trình shell được chỉ định ở đó, truyền tên tệp dưới dạng tham số. (ví dụ: nếu tệp /home/me/foobắt đầu bằng #!/bin/sh, kernel sẽ chạy /bin/sh /home/me/foo).

Tiếp theo trình bao ( bin/shhoặc bất kỳ chương trình thông dịch nào đã được chỉ định) đọc tệp. Shell không biết gì về các dòng shebang nhưng nó vẫn sẽ đọc dòng đầu tiên vì nó giống như bất kỳ dòng nào khác trong tệp ... nó đọc tất cả. Bạn không muốn cái vỏ bị sập hoặc thay đổi hành vi của nó theo bất kỳ cách nào ... cách để làm điều đó là làm cho nó được coi là một nhận xét và bỏ qua nó. Do đó, ký tự tốt nhất cho một lệnh kernel bắt đầu sẽ là ký tự nhận xét.


Có thực sự là hạt nhân làm điều đó không, có vẻ như nó là lớp vỏ hiện tại mà bạn làm việc sẽ phân tích cú pháp shebang và sau đó đẩy kịch bản
Johan

Không ... đó là hạt nhân, sống và trực tiếp. Nó sẽ hoạt động ngay cả khi bạn không sử dụng shell để thực thi tập lệnh ... có nhiều cách khác để thực thi tệp ngoài shell ... ví dụ từ chương trình C, sử dụng lệnh gọi hệ thống "exec"
JoelFan

vi.wikipedia.org/wiki/Shebang_(Unix)#Magic_number "#!" trong ascii là các byte 0x23 0x21 - khi exec () thấy các byte này, hành vi là coi phần còn lại của dòng là đường dẫn đến trình thông dịch.
Aaron McMillin

1

Nó cần phải là một bình luận bởi vì chỉ có cách này nó cũng sẽ hoạt động để chạy một tập lệnh như "phiên bản tên người dùng". Tôi không biết về nguồn gốc của "!".


1
Ngay cả khi bạn chỉ chạy ./scriptname, trình thông dịch vẫn nhìn thấy dòng she-bang, vì vậy nó vẫn cần phải là một nhận xét.
psusi

1
Hoặc để chi tiết hơn: shebang: '#!' được thiết kế để người phiên dịch không nhìn thấy - do đó nó phải bắt đầu bằng chú thích char '#'. Thay vào đó, nó được 'nhìn thấy' (và được giải thích) bởi bộ lệnh 'exec [lv] *' của kernel.
thân
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.