2015-10-29 21 views
10

Tôi đã sử dụng shebang #! một thời gian và hôm nay đã bắt gặp một trường hợp sử dụng làm tôi bối rối.Shebang "#!" bắt đầu và "! #" kết thúc?

Có một số cách để chạy scala kịch bản như

#!/usr/bin/env scala 
println("hello world") 

Tuy nhiên, tôi đã xem qua phiên bản này của công việc

#!/bin/sh 
exec scala "$0" "[email protected]" 
!# 
println("hello world") 

Hình như giải pháp này về cơ bản sẽ gọi bash đầu tiên, chạy exec scala "$0" "[email protected]" nơi $0 biểu thị tên tệp hiện tại và [email protected] là đối số đầu vào trong một mảng vị trí.

Câu hỏi của tôi là điều đó có nghĩa tất cả mọi thứ giữa #!!# có thể được thực hiện trong bash,

#!/bin/sh 
exec scala "$0" "[email protected]" 
echo "oh Yeah" 
!# 
println("hello world") 

Nó không lôi ra nhưng không phải cho tôi "Oh yeah" trong stdout, bất cứ ai có thể giải thích cho tôi đang làm gì ở đây?


update: sau khi nhận ra !# là một điều scala, tôi đã tải về mã nguồn của scala và nhận ra nó chỉ xuất hiện trong các bình luận của ScriptRunner.scala phần được viết bởi Lex Spoon.

+3

'exec' thay thế quy trình hiện tại bằng quy trình mới. Không có gì sau khi nó chạy. –

+0

@EtanReisner, thì trình thông dịch mới (trình thông dịch scala) trong trường hợp này biết nó nên bắt đầu từ 'println()' và không phải là 'echo', là nơi'! # 'Được sử dụng cho? –

+0

Nói cách khác, bạn có thể nhận được 'echo' xuất hiện nếu được đặt trước' exec'.Perl ghi lại một số ký hiệu liên quan trong ['perldoc perlrun'] (http://perldoc.perl.org/perlrun.html). –

Trả lời

9

Đường !# không có ý nghĩa cho vỏ.

Dòng #!/bin/sh có nghĩa là tập lệnh được thực thi bởi /bin/sh. Dòng exec scala "$0" "[email protected]" gọi scala, chuyển tên của tập lệnh và các đối số của nó tới lệnh scala. Vì exec không trả lại, trình bao sẽ không thấy phần còn lại của tập lệnh.

Tôi không biết Scala, nhưng dự đoán của tôi là người phiên dịch Scala xử lý mọi thứ từ đường dây #! đến dòng !# làm nhận xét. Sau đó nó bắt đầu thực hiện với câu lệnh Scala println("hello world").

Trong ngắn, !# là cú pháp Scala, không phải cú pháp vỏ (nhưng cú pháp Scala được thiết kế để cho nó được sử dụng như thế này trong một kịch bản lệnh shell).

Để xem nhanh Scala Language Specification, tôi chưa tìm hiểu cách xác định điều này. Nó được đề cập, nhưng không được giải thích, trong this question. Nó có khả năng, như bình luận của chepner 3 cho thấy, đó là một hack trong thông dịch viên Scala chứ không phải là một phần của cú pháp ngôn ngữ thực tế.

som-snytt tìm thấy mã trong trình biên dịch Scala mà thực hiện này here:

object ScriptSourceFile { 
    /** Length of the script header from the given content, if there is one. 
    * The header begins with "#!" or "::#!" and ends with a line starting 
    * with "!#" or "::!#". 
    */ 
... 

Nhưng tôi tự hỏi liệu đó là tài liệu.

+3

Dường như là một bản hack trong bản dịch viên, vì bản thân shebang không phải là một bình luận trong Scala. – chepner

+1

Nó ở đây: https://github.com/scala/scala/blob/2.11.x/src/reflect/scala/reflect/internal/util/SourceFile.scala#L71 –

+0

@ som-snytt: Bạn có biết rằng cho dù đó là tài liệu? –

Các vấn đề liên quan