Setiap program Kotlin yang berjalan di terminal berinteraksi dengan tiga stream standar: standard input (stdin), standard output (stdout), dan standard error (stderr). Pemahaman tentang ketiga stream ini, ditambah kemampuan mengatur exit code dan menghasilkan output berwarna dengan ANSI escape, adalah fondasi bagi siapa pun yang membangun program CLI. Chapter ini membongkar konsep-konsep tersebut dan menunjukkan bagaimana program Kotlin berperilaku ketika outputnya di-pipe (|) atau di-redirect (>).
Tiga Stream Standar #
Sistem operasi Unix menyediakan tiga stream default untuk setiap program yang berjalan di terminal:
| Stream | Nama file descriptor | Di Kotlin | Tujuan |
|---|---|---|---|
| stdin | fd 0 | System.in`` | Membaca input pengguna |
| stdout | fd 1 | System.out | Output normal program |
| stderr | fd 2 | System.err | Pesan error dan diagnostik |
Pemisahan stdout dan stderr memungkinkan kita menjalankan program > output.txt dan tetap melihat pesan error di terminal — stderr tidak ikut di-redirect. Inilah dasar dari filosofi Unix: program yang baik mengirim data ke stdout dan diagnostik ke stderr.
Exit Code dengan exitProcess #
Setiap program CLI mengembalikan exit code (kode keluar) ke shell. Nilai 0 berarti sukses, nilai non-zero berarti ada kesalahan. Di Kotlin, kita dapat mengatur exit code dengan exitProcess(code):
import kotlin.system.exitProcess
fun main(args: Array<String>) {
val mode = args.getOrElse(0) { "stdout" }
when (mode) {
"stdout" -> {
println("Pesan ke stdout")
System.err.println("Pesan ke stderr")
}
"color" -> {
val merah = "\u001B[31m"
val hijau = "\u001B[32m"
val kuning = "\u001B[33m"
val reset = "\u001B[0m"
println("${hijau}SUKSES${reset}: operasi berhasil")
println("${kuning}PERINGATAN${reset}: ada catatan kecil")
println("${merah}GAGAL${reset}: operasi tidak dapat dilanjutkan")
}
"exit" -> {
val kode = args.getOrElse(1) { "0" }.toInt()
println("Keluar dengan kode $kode")
exitProcess(kode)
}
"echo" -> {
var jumlah = 0
while (true) {
val baris = readlnOrNull() ?: break
println("[$jumlah] $baris")
jumlah++
}
println("Total baris: $jumlah")
}
else -> {
println("Penggunaan: program [stdout|color|exit|echo]")
exitProcess(2)
}
}
}Output yang Dihasilkan:
Pesan ke stdoutMari kita telaah baris-baris kode di atas:
- Baris 1 (
import kotlin.system.exitProcess): functionexitProcessberada di packagekotlin.system. Function ini memanggilRuntime.getRuntime().exit(code)di balik layar dan segera menghentikan JVM. - Baris 5 (
args.getOrElse(0) { "stdout" }): argumen pertama menjadi mode operasi program. Jika tidak diberikan, defaultnya"stdout". Pola ini umum di CLI: satu argumen pertama sebagai sub-command. - Baris 9 (
println("Pesan ke stdout")): menulis ke stdout melaluiSystem.out. Pesan ini akan ikut ter-redirect jika output di-pipe. - Baris 10 (
System.err.println(...)): menulis ke stderr melaluiSystem.err. Pesan ini tidak ikut ter-redirect oleh>biasa — hanya redirect khusus2>yang menangkapnya. - Baris 12–19 (
mode == "color"): menggunakan ANSI escape sequence untuk mewarnai output. Sequence\u001B[31mmengaktifkan warna merah,\u001B[32mhijau,\u001B[33mkuning, dan\u001B[0mmereset ke default. - Baris 22 (
exitProcess(kode)): menghentikan program dengan exit code yang diberikan. Setelah pemanggilan ini, kode di bawahnya tidak akan dieksekusi. - Baris 27 (
readlnOrNull() ?: break): pola loop membaca stdin hingga EOF.breakkeluar dari loop saat EOF. Inilah pola filter Unix yang membaca input baris-per-baris. - Baris 35 (
exitProcess(2)): konvensi exit code2untuk kesalahan penggunaan (usage error). Berbeda dengan exit code1yang biasanya berarti error runtime, kode2khusus untuk “argumen tidak valid”.
Exit Code dan Konvensi Unix #
| Kode | Arti konvensional |
|---|---|
0 | Sukses |
1 | Error umum (kegagalan operasi) |
2 | Kesalahan penggunaan (argumen invalid) |
126 | File tidak dapat dieksekusi |
127 | Command tidak ditemukan |
130 | Dihentikan oleh Ctrl+C (SIGINT) |
Shell menangkap exit code di variabel $? setelah program berakhir. Pola program && next menjalankan next hanya jika exit code 0; program || next sebaliknya.
Output Berwarna dengan ANSI Escape #
Terminal modern mendukung ANSI escape sequence untuk mengubah warna teks, latar, dan gaya (tebal, garis bawah). Formatnya selalu diawali \u001B[ dan diakhiri m:
val merah = "\u001B[31m"
val hijau = "\u001B[32m"
val kuning = "\u001B[33m"
val biru = "\u001B[34m"
val tebal = "\u001B[1m"
val reset = "\u001B[0m"
println("${hijau}SUKSES${reset}: operasi berhasil")
println("${merah}${tebal}GAGAL${reset}: operasi tidak dapat dilanjutkan")Beberapa kode warna umum:
| Kode | Warna |
|---|---|
30 / 90 | Hitam / Abu terang |
31 / 91 | Merah / Merah terang |
32 / 92 | Hijau / Hijau terang |
33 / 93 | Kuning / Kuning terang |
34 / 94 | Biru / Biru terang |
0 | Reset semua atribut |
1 | Tebal (bold) |
4 | Garis bawah (underline) |
Untuk warna latar, ganti digit pertama 3 menjadi 4 (misalnya \u001B[41m untuk latar merah).
Pipe dan Redirect #
Shell Unix memungkinkan kita merangkai program dengan pipe | dan redirect >:
# Redirect stdout ke file (stderr tetap ke terminal)
java -jar app.jar stdout > out.txt
# Redirect stdout dan stderr ke file berbeda
java -jar app.jar stdout > out.txt 2> err.txt
# Redirect keduanya ke file yang sama
java -jar app.jar stdout > all.txt 2>&1
# Pipe output program A ke input program B
java -jar app.jar echo | grep "satu"Saat program di-pipe, System.out tidak lagi terhubung ke terminal melainkan ke pipe. Method System.console() mengembalikan null ketika stdout adalah pipe — trik ini sering dipakai untuk mendeteksi apakah output akan ditampilkan ke pengguna atau diproses lebih lanjut.
Pola Unix Filter #
Program echo mode di app.kt menggambarkan pola Unix filter: baca stdin baris-per-baris, proses, tulis ke stdout. Pola ini dapat dirangkai dengan program lain:
printf "apel\njeruk\nmangga\n" | java -jar app.jar echo | grep "jeruk"
# Output: [1] jerukFilter kecil yang melakukan satu tugas dengan baik adalah dasar filosofi Unix. Banyak tool CLI klasik (grep, sed, awk, sort, uniq) mengikuti pola ini.
Referensi Lanjutan #
- Kotlin stdlib kotlin.io
— paket
kotlin.iountukprintln,print, danreadlndi program CLI - Java SE 21 System
— dokumentasi
java.lang.SystemJava SE 21 untukSystem.in,out,err, danexit
Dengan pemahaman tentang stream, exit code, ANSI color, dan perilaku pipe, kita menutup section Input/Output dan Formatting. Pada section berikutnya, kita akan menyelami topik yang lebih dalam tentang struktur kontrol Kotlin: control flow dengan if, when, dan loop.