skip to content

How do you read command-line arguments and set a process exit code from a Kotlin `main`?

level: middleimportance: should knowfreq 45%

answer

  1. args: Array<String> holds CLI arguments
  2. args[0] is the first real arg (no program name)
  3. main returns Unit, not an Int code
  4. exitProcess(code) sets the exit status, returns Nothing
  5. Non-zero code = failure by convention

basics

~10 s

Command-line arguments arrive as the args: Array<String> parameter of main. To end the program with a specific status code, call kotlin.system.exitProcess(code) — for example exitProcess(1) to signal failure.

solid answer

~40 s

You read arguments via `fun main(args: Array<String>)`; `args` is an ordinary `Array<String>` you can index, iterate, or destructure (e.g. `args.getOrNull(0)`). `main` itself returns `Unit`, so it cannot return an exit code the way C's `int main` does. To control the process exit status, call `kotlin.system.exitProcess(status)`, which delegates to `System.exit` on the JVM, immediately terminating the JVM with that code (0 = success by convention). Because `exitProcess` halts abruptly, run any cleanup before it or rely on JVM shutdown hooks. For argument parsing beyond trivial cases, use a library like `kotlinx-cli` or `clikt` rather than hand-rolling. Note `args` excludes the program name, so `args[0]` is the first real argument.

code

kotlin · 11 lines
kotlin
import kotlin.system.exitProcess

fun main(args: Array<String>) {
    val n = args.getOrNull(0)?.toIntOrNull()
    if (n == null) {
        System.err.println("expected an integer argument")
        exitProcess(2)
    }
    println("squared = ${n * n}")
    // implicit exit code 0 on normal return
}

go deeper

for a junior

Reads args and knows exitProcess(code) ends the program with a status.

for a middle

Explains args excludes program name, main returns Unit, and exitProcess returns Nothing / calls System.exit.

for a senior

Discusses abrupt termination, shutdown hooks, uncaught-exception exit paths, and choosing a CLI parser.

for a principal

Designs CLI contracts (exit-code conventions, error streams, signal handling) and how they integrate with orchestration/CI tooling.

## Reading arguments When the program is started with parameters, they are delivered as the `args` parameter: ```kotlin import kotlin.system.exitProcess fun main(args: Array<String>) { if (args.isEmpty()) { System.err.println("usage: tool <name>") exitProcess(2) // non-zero = error } val name = args[0] // first REAL argument println("Hello, $name") } ``` Key points: - `args` is a plain `Array<String>`. Use `args.size`, `args.getOrNull(i)` (safe), `args.firstOrNull()`, or iterate with `for (a in args)`. - **`args` does not include the program/jar name.** `args[0]` is the first user argument, unlike C's `argv[0]`. - For real CLIs, prefer a parser library: `kotlinx-cli` or `clikt` handle flags, options, and help text. ## Setting the exit code `main` returns `Unit` — it cannot return an integer status. The exit code is set explicitly: ```kotlin import kotlin.system.exitProcess exitProcess(0) // success exitProcess(1) // generic failure ``` - `kotlin.system.exitProcess(status: Int): Nothing` returns `Nothing` (it never returns normally) and on the JVM calls `System.exit(status)`, which **immediately terminates the JVM** with that status code. - By POSIX convention, `0` means success and any non-zero value means failure; shells read it as `$?`. - Because it's abrupt, code after `exitProcess(...)` is unreachable. Do cleanup first, or register a `Runtime.getRuntime().addShutdownHook { ... }`. ## Why not just `return`? Returning from `main` ends the program with exit code `0` (assuming no non-daemon threads keep the JVM alive). To signal failure you must call `exitProcess` (or throw an uncaught exception, which exits with a non-zero code and prints a stack trace). ## Uncaught exceptions If `main` throws and nothing catches it, the JVM prints the stack trace to `stderr` and exits with a non-zero status — a common implicit "failure" path. ## Key keywords/APIs - `args: Array<String>` — the arguments. - `kotlin.system.exitProcess(code): Nothing` — set exit status / terminate. - `Nothing` — the return type signaling no normal return. - `args.getOrNull`, `firstOrNull` — safe access. - `kotlinx-cli` / `clikt` — argument parsers.

  • What exit code does a Kotlin program return if `main` simply finishes normally?
    0 (success), provided no non-daemon threads keep the JVM running and no uncaught exception occurred.
  • What is the return type of `exitProcess` and why?
    `Nothing`, because it never returns normally — it terminates the process — so the compiler treats code after it as unreachable.

main can't hand back a receipt (no return code), so exitProcess is the bell you ring on the way out to announce success or failure.

saying these in an interview costs you the question

  • Returning an Int from main expecting it to set the exit code
  • Treating args[0] as the program name
  • Putting cleanup logic after exitProcess (unreachable)
  • Not knowing exitProcess maps to System.exit on the JVM
  • Using args.get(0) without guarding against an empty array

context