Shebang
This guide explains the differences between the run
and shebang
sub-commands, mainly covering how each of them
parses its arguments.
shebang
script headers
Before proceeding, let's discuss how Scala CLI works in a script without the shebang
command.
Here is a simple hello.sc
script with a shebang
header:
#!/usr/bin/env -S scala-cli -S 3
println(args.size)
println(args.headOption)
And it works correctly:
chmod +x hello.sc
./hello.sc
0
None
And it also works:
./hello.sc -- Hello World
2
Some(Hello)
Note that the extra --
must be added to make it work. If it is not supplied, the result is:
./hello.sc Hello World
[error] Hello: input file not found
World: input file not found
If we modify our script slightly and use the shebang
sub-command in the header, we will get the following:
#!/usr/bin/env -S scala-cli shebang -S 3
println(args.size)
println(args.headOption)
./hello.sc Hello World
2
Some(Hello)
shebang
and the command line
Let's now see how the shebang
command works straight from the command line.
object Main {
def main(args: Array[String]): Unit = println(args.mkString(" "))
}
scala-cli shebang Main.scala Hello world
Hello world
Please note that shebang
changing how arguments are parsed means that every option after the first input will be treated as
an argument to the app.
scala-cli shebang Main.scala -S 2.13 #-S 2.13 is not recognised as an option, but as app arguments
-S 2.13
If we try to do the same with the run
sub-command, we get the following error:
scala-cli run Main.scala Hello world
[error] Hello: input file not found
world: input file not found
Script files' extensions
When running the shebang
subcommand, script files don't need the .sc
extension,
but they are then REQUIRED to start with a shebang line:
#!/usr/bin/env -S scala-cli shebang -S 3
println(args.size)
println(args.headOption)
chmod +x hello-with-shebang
./hello-with-shebang Hello World
2
Some(Hello)
println(args.size)
println(args.headOption)
chmod +x hello-no-shebang
scala-cli shebang hello-no-shebang Hello World
hello-no-shebang: unrecognized source type (expected .scala or .sc extension, or a directory)
Files with no extensions are always run as scripts even though they may contain e.g. valid .scala
program.