Program command line jarang berdiri sendiri: program membaca cara pemanggilannya dari argumen, membaca konfigurasi dari environment variable, dan melaporkan keberhasilan melalui kode keluar. Package os menjadi jembatan antara program Go dan sistem operasi untuk ketiganya. Chapter ini mempraktikkan os.Args, Getenv, Setenv, LookupEnv, Environ, standard stream, dan os.Exit dengan contoh yang dijalankan sungguhan.
Membaca Argumen dengan os.Args #
Variable os.Args adalah slice string yang memuat seluruh kata pada command line. Indeks 0 berisi nama program, sedangkan argumen pengguna dimulai dari indeks 1:
argumen := os.Args[1:]Saat dijalankan lewat go run, indeks 0 berisi path binary sementara yang berubah di setiap eksekusi. Program demo karena itu hanya mencetak elemen mulai indeks 1 supaya output tetap stabil.
Environment Variable: Getenv, Setenv, dan LookupEnv #
Environment variable adalah pasangan kunci-nilai yang diwarisi program dari proses pemanggilnya. Fungsi os.Setenv membuat atau mengubah variabel; os.Getenv membaca nilainya. Perilaku keduanya saat variabel tidak ada berbeda:
| Kondisi variabel | os.Getenv | os.LookupEnv |
|---|---|---|
Ada, bernilai "produksi" | "produksi" | "produksi", true |
Ada, bernilai kosong "" | "" | "", true |
| Tidak ada | "" | "", false |
os.Getenv tidak bisa membedakan variabel kosong dari variabel yang tidak ada karena keduanya mengembalikan "". Fungsi os.LookupEnv mengembalikan nilai kedua bertipe boolean — bentuk dua-nilai ini (bahasa Inggris: comma ok idiom) menjawab keraguan tersebut.
Daftar Seluruh Variabel dengan os.Environ #
Fungsi os.Environ() mengembalikan slice string berformat KUNCI=nilai untuk seluruh variabel lingkungan. Isinya berbeda di setiap mesin, jadi program demo memakai pola stabil: menyaring variabel berprefiks PELATIHAN_ milik sendiri, lalu mengurutkannya dengan sort.Strings.
Standard Stream dan os.File #
os.Stdout, os.Stderr, dan os.Stdin bertipe *os.File. Tipe tersebut memenuhi interface io.Writer dan io.Reader, sehingga ketiganya bisa dipakai di fungsi mana pun yang menerima kedua interface itu — contohnya fmt.Fprintf(os.Stdout, ...). Untuk bekerja dengan berkas fisik, chapter Membaca File
dan Menulis File
membahas os.Open dan os.Create.
Program Utuh #
Berkas os-demo.go menggabungkan seluruh materi di atas:
package main
import (
"fmt"
"os"
"sort"
"strings"
)
func main() {
// os.Args[0] berisi nama program; argumen pengguna mulai dari indeks 1.
argumen := os.Args[1:]
fmt.Println("jumlah argumen:", len(argumen))
for indeks, nilai := range argumen {
fmt.Printf("argumen[%d] = %s\n", indeks, nilai)
}
// Setenv membuat variabel lingkungan, Getenv membaca nilainya.
os.Setenv("NAMA_APLIKASI", "kasir")
fmt.Println("getenv NAMA_APLIKASI:", os.Getenv("NAMA_APLIKASI"))
fmt.Printf("getenv VARIABEL_TIDAK_ADA: %q\n", os.Getenv("VARIABEL_TIDAK_ADA"))
// LookupEnv melaporkan apakah variabel benar-benar ada.
os.Setenv("MODE_APLIKASI", "produksi")
mode, ada := os.LookupEnv("MODE_APLIKASI")
fmt.Printf("lookupenv MODE_APLIKASI: %q ada: %v\n", mode, ada)
kosong, hilang := os.LookupEnv("VARIABEL_TIDAK_ADA")
fmt.Printf("lookupenv VARIABEL_TIDAK_ADA: %q ada: %v\n", kosong, hilang)
// os.Environ memuat semua variabel; saring milik kita lalu urutkan.
os.Setenv("PELATIHAN_KOTA", "Bandung")
os.Setenv("PELATIHAN_MATERI", "standard library")
terpilih := []string{}
for _, kv := range os.Environ() {
if strings.HasPrefix(kv, "PELATIHAN_") {
terpilih = append(terpilih, kv)
}
}
sort.Strings(terpilih)
fmt.Println("environ terfilter:", strings.Join(terpilih, ", "))
// os.Stdout bertipe *os.File dan memenuhi io.Writer.
fmt.Fprintf(os.Stdout, "fmt.Fprintf ke os.Stdout berhasil\n")
// os.Exit menghentikan program seketika; defer tidak dijalankan.
defer fmt.Println("baris defer ini tidak pernah tercetak")
fmt.Println("program selesai")
os.Exit(0)
}Jalankan tanpa argumen terlebih dahulu:
go run os-demo.goOutput yang Dihasilkan:
jumlah argumen: 0
getenv NAMA_APLIKASI: kasir
getenv VARIABEL_TIDAK_ADA: ""
lookupenv MODE_APLIKASI: "produksi" ada: true
lookupenv VARIABEL_TIDAK_ADA: "" ada: false
environ terfilter: PELATIHAN_KOTA=Bandung, PELATIHAN_MATERI=standard library
fmt.Fprintf ke os.Stdout berhasil
program selesaiKemudian jalankan lagi dengan dua argumen:
go run os-demo.go Budi SitiOutput yang Dihasilkan:
jumlah argumen: 2
argumen[0] = Budi
argumen[1] = Siti
getenv NAMA_APLIKASI: kasir
getenv VARIABEL_TIDAK_ADA: ""
lookupenv MODE_APLIKASI: "produksi" ada: true
lookupenv VARIABEL_TIDAK_ADA: "" ada: false
environ terfilter: PELATIHAN_KOTA=Bandung, PELATIHAN_MATERI=standard library
fmt.Fprintf ke os.Stdout berhasil
program selesaiMari kita telaah baris demi baris program di atas:
- Baris 12-16:
os.Args[1:]mengambil argumen pengguna, lalu loop mencetak indeks dan nilai setiap argumen; tanpa argumen, loop tidak berputar sama sekali. - Baris 19-21:
os.Setenvmembuat variabelNAMA_APLIKASI,os.Getenvmembacanya kembali; verb%qmemperlihatkan string kosong yang dikembalikan untuk variabel yang tidak ada. - Baris 24-29:
os.LookupEnvdiuji pada dua kondisi — variabel yang ada (adabernilaitrue) dan variabel yang hilang (hilangbernilaifalse). - Baris 32-41: dua variabel berprefiks
PELATIHAN_dibuat, hasilos.Environdisaring denganstrings.HasPrefix, lalusort.Stringsmenjamin urutan cetak yang tetap. - Baris 44:
fmt.Fprintfmenulis keos.Stdout, bukti bahwa*os.Filememenuhiio.Writer. - Baris 46-49:
deferterdaftar pada baris 47, tetapios.Exit(0)pada baris 49 menghentikan program sebelum baris defer tersebut sempat dijalankan.
Keluar Program dengan os.Exit #
Fungsi os.Exit menghentikan program seketika dengan kode status tertentu. Konvensinya: kode 0 berarti sukses, kode lain berarti gagal; script shell dan sistem CI membaca kode ini lewat $?.
Berkas os-exit-demo.go memperagakan kedua kode keluar:
package main
import (
"fmt"
"os"
)
func main() {
kode := 0
if len(os.Args) > 1 && os.Args[1] == "gagal" {
kode = 1
}
fmt.Println("keluar dengan kode", kode)
os.Exit(kode)
}Tanpa argumen, program keluar dengan kode 0:
go run os-exit-demo.goOutput yang Dihasilkan:
keluar dengan kode 0Dengan argumen gagal, program keluar dengan kode 1 dan kode tersebut terbaca oleh $?:
go run os-exit-demo.go gagal
echo "kode keluar: $?"Output yang Dihasilkan:
keluar dengan kode 1
kode keluar: 1Mari kita telaah baris demi baris program di atas:
- Baris 9 (
kode := 0): menetapkan kode keluar bawaan, yaitu sukses. - Baris 10-12: memeriksa argumen pertama; jika nilainya
"gagal", kode keluar diubah menjadi 1. - Baris 13: mencetak kode yang akan dipakai agar hasilnya terlihat di layar.
- Baris 14 (
os.Exit(kode)): menghentikan program dan meneruskankodesebagai status proses kepada sistem operasi.
Saat menguji lewat go run, perintah tersebut turut mencetak exit status 1 ke standard error; kode status tetap diteruskan ke $?.
Referensi #
- Dokumentasi package os — seluruh fungsi interaksi sistem operasi.
- os.Getenv — perilaku Getenv dan LookupEnv.
- os.Environ — format dan jaminan nilai kembalian.
- os.Exit — kontrak kode status proses.
Package os memberi akses mentah ke argumen, variabel lingkungan, dan kode keluar. Chapter berikutnya naik satu tingkat abstraksi ke package io: dua interface kecil bernama Reader dan Writer yang menjadi bahasa bersama seluruh input-output di Go.
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
os-demo.go
Unduh berkaspackage main
import (
"fmt"
"os"
"sort"
"strings"
)
func main() {
// os.Args[0] berisi nama program; argumen pengguna mulai dari indeks 1.
argumen := os.Args[1:]
fmt.Println("jumlah argumen:", len(argumen))
for indeks, nilai := range argumen {
fmt.Printf("argumen[%d] = %s\n", indeks, nilai)
}
// Setenv membuat variabel lingkungan, Getenv membaca nilainya.
os.Setenv("NAMA_APLIKASI", "kasir")
fmt.Println("getenv NAMA_APLIKASI:", os.Getenv("NAMA_APLIKASI"))
fmt.Printf("getenv VARIABEL_TIDAK_ADA: %q\n", os.Getenv("VARIABEL_TIDAK_ADA"))
// LookupEnv melaporkan apakah variabel benar-benar ada.
os.Setenv("MODE_APLIKASI", "produksi")
mode, ada := os.LookupEnv("MODE_APLIKASI")
fmt.Printf("lookupenv MODE_APLIKASI: %q ada: %v\n", mode, ada)
kosong, hilang := os.LookupEnv("VARIABEL_TIDAK_ADA")
fmt.Printf("lookupenv VARIABEL_TIDAK_ADA: %q ada: %v\n", kosong, hilang)
// os.Environ memuat semua variabel; saring milik kita lalu urutkan.
os.Setenv("PELATIHAN_KOTA", "Bandung")
os.Setenv("PELATIHAN_MATERI", "standard library")
terpilih := []string{}
for _, kv := range os.Environ() {
if strings.HasPrefix(kv, "PELATIHAN_") {
terpilih = append(terpilih, kv)
}
}
sort.Strings(terpilih)
fmt.Println("environ terfilter:", strings.Join(terpilih, ", "))
// os.Stdout bertipe *os.File dan memenuhi io.Writer.
fmt.Fprintf(os.Stdout, "fmt.Fprintf ke os.Stdout berhasil\n")
// os.Exit menghentikan program seketika; defer tidak dijalankan.
defer fmt.Println("baris defer ini tidak pernah tercetak")
fmt.Println("program selesai")
os.Exit(0)
}
os-exit-demo.go
Unduh berkaspackage main
import (
"fmt"
"os"
)
func main() {
kode := 0
if len(os.Args) > 1 && os.Args[1] == "gagal" {
kode = 1
}
fmt.Println("keluar dengan kode", kode)
os.Exit(kode)
}