2015-10-29 17 views
10

Ho usato per un po 'lo shebang #! e oggi ho trovato un caso d'uso che mi confonde.Shebang "#!" inizia e "! #" termina?

Ci sono diversi modi per eseguire lo script Scala come

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

Tuttavia, mi sono imbattuto in questa versione di shebang

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

Sembra che questa soluzione richiama fondamentalmente la bash prima, la corsa exec scala "$0" "[email protected]" dove $0 indica il nome file corrente e [email protected] è argomenti di input in una matrice posizionale.

la mia domanda è vuol dire tutto tra #! e !# potrebbe essere eseguita in bash,

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

Non ha errore fuori ma nessuno mi ha dato la "Oh Yeah" in stdout, qualcuno può spiegare a me cosa sta succedendo qui?


aggiornamento: dopo aver realizzato !# è una cosa Scala, ho scaricato il codice sorgente di Scala e ho capito che appare solo nel commento di ScriptRunner.scala parte scritta da Lex Spoon.

+3

'exec' sostituisce il processo corrente con il nuovo processo. Niente dopo che corre. –

+0

@EtanReisner, allora come sa che il nuovo interprete (scala interpreter) in questo caso sa che dovrebbe iniziare da 'println()' e non da 'echo', è quello dove viene usato'! # '? –

+0

In altre parole, potresti essere in grado di visualizzare l'echo se posto prima di 'exec'.Perl documenta alcune notazioni correlate in ['perldoc perlrun'] (http://perldoc.perl.org/perlrun.html). –

risposta

9

La riga !# non ha alcun significato nella shell.

La riga #!/bin/sh indica che lo script viene eseguito da /bin/sh. La riga exec scala "$0" "[email protected]" invoca scala, passando il nome dello script e i relativi argomenti al comando scala. Poiché exec non ritorna, la shell non vede il resto dello script.

Non conosco Scala, ma la mia ipotesi istruita è che l'interprete Scala tratti tutto dalla linea #! alla riga !# come commento. Inizia quindi l'esecuzione con l'istruzione Scala println("hello world").

In breve il !# è sintassi Scala, non la sintassi della shell (ma la sintassi di Scala è progettata per essere utilizzata in questo modo in uno script di shell).

In una rapida occhiata allo Scala Language Specification, non ho scoperto come questo è definito. Viene menzionato, ma non spiegato, in this question. È probabile, come suggerisce il commento di chepner 3, che si tratta di un trucco nell'interprete di Scala piuttosto che parte della sintassi del linguaggio reale.

som-snytt trovato il codice nell'interprete Scala che implementa questa 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 "::!#". 
    */ 
... 

Ma mi chiedo se è documentato.

+3

Sembra essere un hack nell'interprete stesso, dal momento che lo shebang non è un commento in Scala. – chepner

+1

È qui: https://github.com/scala/scala/blob/2.11.x/src/reflect/scala/reflect/internal/util/SourceFile.scala#L71 –

+0

@ som-snytt: ti capita di sapere se è documentato? –

Problemi correlati