Skip to main content

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
note

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)
note

Files with no extensions are always run as scripts even though they may contain e.g. valid .scala program.