Menulis skrip BASH pertama dengan benar: memahami baris shebang dan perbedaan #!/bin/bash dengan /usr/bin/env bash, mengatur izin eksekusi dengan chmod +x, serta membedah tiga cara menjalankan skrip — sebagai program, sebagai argumen interpreter, dan sebagai source.

Setelah di episode 1 sebelumnya kita membedah sejarah — bahwa BASH lahir dari Bourne Shell, menjadi standar de facto, dan berdiri di antara sh, zsh, serta bahasa tingkat tinggi — pada episode kali ini kita akhirnya menulis skrip pertama yang sesungguhnya. Episode 2 ini adalah titik di mana teori berubah menjadi praktik: kalian akan menulis file, menjadikannya executable, dan menjalankannya lewat tiga cara berbeda yang perilakunya tidak sama.
Topik episode ini terlihat sederhana — baris pertama yang bernama shebang, satu perintah chmod +x, dan tiga cara menjalankan skrip. Tapi jangan tertipu: kesalahpahaman di sini adalah sumber dari sekian banyak misteri yang membuat pemula frustrasi. Mengapa skrip jalan dengan bash skrip.sh tapi gagal dengan ./skrip.sh? Mengapa variabel yang di-set di dalam skrip "hilang" begitu skrip selesai? Mengapa file yang dibuat di Windows error aneh di Linux? Semua jawabannya ada di episode ini.
Setiap skrip BASH yang baik dibuka dengan dua karakter #! di baris pertama. Kombinasi ini disebut shebang (atau hashbang). Ia bukan komentar — ia adalah instruksi kepada kernel: "jalankan file ini dengan interpreter yang saya tunjuk."
#!/bin/bash
echo "Hello, BASH Scripting!"Saat kalian mengetik ./skrip.sh di terminal, kernel membaca dua byte pertama #!, lalu menemukan path /bin/bash, dan menyerahkan seluruh file kepada BASH untuk dieksekusi. Tanpa shebang, sistem tidak tahu interpreter mana yang dipakai — dan kalian akan mendapat error Permission denied atau harus memanggil interpreter secara manual.
Analoginya: shebang seperti label "Lampirkan ke departemen terkait" pada surat. Kernel adalah pos terdepan yang membaca label itu dan meneruskan surat (skrip) ke meja yang tepat (interpreter BASH). Tanpa label, surat itu bingung mau dikirim ke mana.
#!/bin/bash vs #!/usr/bin/env bashDua varian yang paling umum:
| Shebang | Cara kerja | Kapan dipakai |
|---|---|---|
#!/bin/bash | Memanggil BASH langsung dari path absolut /bin/bash | Paling umum di server; deterministik |
#!/usr/bin/env bash | Mencari bash dari $PATH | Lebih portabel di sistem non-Linux (BSD, macOS dengan Homebrew) |
Mengapa ada dua pilihan? Di Linux, /bin/bash hampir selalu ada. Tapi di sistem lain, BASH bisa berada di tempat berbeda — misalnya /opt/homebrew/bin/bash di macOS dengan Homebrew. #!/usr/bin/env bash memecahkan masalah itu dengan mencari bash di mana pun $PATH menunjuk.
Trade-off-nya: env memakai $PATH, jadi jika $PATH aneh (misalnya environment di cron yang sangat minimal), env bash bisa menunjuk ke lokasi yang salah. Untuk series ini — dan untuk mayoritas skrip server Linux — #!/bin/bash adalah pilihan yang tepat, aman, dan deterministik.
Note
Apakah kalian memakai #!/bin/bash atau #!/usr/bin/env bash, yang penting: selalu berada di baris pertama, tanpa spasi di depannya, dan tanpa spasi di dalam path. Kesalahan kecil di sini menghasilkan error yang membingungkan — kita bahas di bagian pitfalls.
hello.shMari menulis skrip pertama. Buat file bernama hello.sh di folder latihan kalian:
#!/bin/bash
echo "Hello, BASH Scripting!"
echo "Tanggal hari ini: $(date +%A)"
echo "Sistem ini bernama: $(hostname)"bash hello.shHello, BASH Scripting!
Tanggal hari ini: Minggu
Sistem ini bernama: arman-vmPerhatikan: $(date +%A) dan $(hostname) adalah command substitution — hasil perintah dimasukkan ke dalam string. Kita tidak akan membedahnya sekarang (ada episode khusus), tapi lihat betapa mudahnya merangkai output perintah ke dalam teks — inilah kekuatan BASH yang akan kalian pakai terus.
chmod +x: Memberi Izin Menjadi ProgramMenjalankan dengan bash hello.sh tidak butuh izin eksekusi — kalian memanggil interpreter secara manual. Tapi untuk menjalankan ./hello.sh, file harus memiliki izin eksekusi. Di sinilah chmod +x berperan:
chmod +x hello.sh
./hello.shHello, BASH Scripting!Sekarang kalian bisa mengecek perbedaannya di metadata file:
ls -l hello.sh-rwxr-xr-x 1 arman arman 89 Agu 2 10:00 hello.shTanda -rwxr-xr-x berarti: owner bisa baca-tulis-eksekusi (rwx), group dan others bisa baca-eksekusi (r-x). Izin eksekusi (x) inilah yang memungkinkan kernel memanggil file sebagai program. Tanpa chmod +x, ./hello.sh akan menolak dengan Permission denied.
Tip
chmod +x menambah izin eksekusi untuk semua kategori (user, group, others). Untuk skrip pribadi cukup chmod u+x hello.sh (hanya owner). Detail permission — termasuk mode oktal seperti 755 dan 644 — dibahas mendalam di series Belajar Linux episode permission, tapi prinsipnya: skrip butuh x agar bisa dieksekusi sebagai program.
Inilah bagian paling penting di episode ini — dan sumber kebingungan paling umum. Ada tiga cara menjalankan skrip, dan ketiganya tidak sama:
| Cara | Sintaks | Proses baru? | Lingkungan? |
|---|---|---|---|
| Program | ./hello.sh | Ya, subshell baru | Mewarisi environment, perubahan tidak kembali |
| Argumen interpreter | bash hello.sh | Ya, subshell baru | Sama seperti di atas |
| Source | source hello.sh atau . hello.sh | Tidak — berjalan di shell saat ini | Perubahan variabel bertahan di shell |
Mari bedah satu per satu dengan analogi: bayangkan skrip adalah lembar instruksi.
./hello.sh — kalian menyerahkan lembar instruksi kepada seorang karyawan baru (proses subshell). Karyawan itu menyelesaikan tugasnya di mejanya sendiri, lalu pulang. Apa pun yang dia tulis di papan tulisnya (variabel) hilang saat dia pulang.
bash hello.sh — sama dengan di atas, tapi kalian yang memilihkan interpreternya secara manual alih-alih membiarkan shebang menentukannya. Karena itu, ia berjalan meski file tidak punya izin x.
source hello.sh (atau singkatnya . hello.sh) — kalian membacakan instruksinya sendiri di mejamu, baris demi baris, di shell yang sama. Apa pun yang kalian tulis di papan tulismu (variabel) tetap ada setelah selesai.
Perbedaan ini sangat menentukan. Mari buktikan dengan eksperimen.
exportBuat dua skrip kecil:
#!/bin/bash
export MESSAGE="Dari dalam skrip"
echo "MESSAGE di dalam skrip: $MESSAGE"bash setenv.sh
echo "setelah bash setenv.sh : [$MESSAGE]"
. setenv.sh
echo "setelah source setenv.sh : [$MESSAGE]"MESSAGE di dalam skrip: Dari dalam skrip
MESSAGE di dalam skrip: Dari dalam skrip
setelah bash setenv.sh : []
setelah source setenv.sh : [Dari dalam skrip]Perhatikan hasilnya:
bash setenv.sh, skrip berjalan di subshell — variabel MESSAGE dibuat di subshell itu dan hilang begitu skrip selesai. $MESSAGE di shell utama tetap kosong.source setenv.sh, skrip berjalan di shell kalian sendiri — variabel MESSAGE bertahan dan terlihat setelahnya.Ini mengapa file konfigurasi (seperti .bashrc) di-source, bukan dijalankan sebagai program: kalian ingin perubahannya menempel pada shell saat ini, bukan hilang di subshell.
Important
Pilihan mode eksekusi harus disesuaikan dengan tujuan. Ingin skrip mengubah lingkungan shell kalian (alias, variabel, fungsi)? Gunakan source. Ingin skrip berjalan mandiri dan terisolasi (backup, deployment, cron)? Gunakan ./skrip.sh atau bash skrip.sh. Menggunakan cara yang salah adalah akar dari "variabel hilang misterius" — bukan bug, tapi kesalahan memilih mode eksekusi.
| Kebutuhan | Mode yang tepat | Contoh nyata |
|---|---|---|
| Menjalankan task otomasi | ./skrip.sh | ./deploy.sh, ./backup.sh |
| Menjalankan tanpa izin eksekusi | bash skrip.sh | bash setup.sh di sistem orang lain |
| Memuat konfigurasi ke shell | source / . | . ~/.bashrc, source env.local |
| Menjalankan skrip yang men-set variabel untuk sesi | source | source venv/bin/activate |
Aturan praktis yang dipegang sysadmin: default-nya ./skrip.sh (menghormati shebang dan izin eksekusi); gunakan source hanya saat memang ingin memengaruhi shell saat ini.
Sekarang kalian tahu inti perbedaannya, mari formalisasikan. Ketika kalian menjalankan ./skrip.sh atau bash skrip.sh, shell utama membuat fork — proses anak (subshell) yang mewarisi environment (variabel yang di-export) tetapi menjalankan instruksinya di ruang sendiri. Segala perubahan di dalamnya — variabel, cd, export — tidak memengaruhi induk.
Sebaliknya, source tidak membuat proses baru. Skrip dieksekusi baris demi baris di dalam shell saat ini, persis seperti kalian mengetiknya sendiri. cd di dalam skrip akan mengubah direktori shell kalian; export akan berlaku untuk semua perintah berikutnya.
cat > whereami.sh <<'EOF'
#!/bin/bash
cd /tmp
echo "Sekarang di: $PWD"
EOF
bash whereami.sh
echo "Shell utama masih di : $PWD"Sekarang di: /tmp
Shell utama masih di : /home/arman/labJika kalian mengganti bash whereami.sh dengan source whereami.sh, shell utama ikut pindah ke /tmp. Eksperimen ini membuat perbedaan subshell vs source terasa secara langsung.
Lupa chmod +x lalu mengetik ./skrip.sh. Error Permission denied bukan berarti skrip salah — file-nya belum executable. Solusinya chmod +x skrip.sh. Inilah alasan bash skrip.sh "jalan" padahal ./skrip.sh tidak.
Shebang dengan spasi. #! /bin/bash (ada spasi setelah #!) tidak didukung semua sistem. Tulis tanpa spasi: #!/bin/bash.
Shebang bukan di baris pertama. Shebang harus baris pertama. Jika ada baris kosong atau komentar di atasnya, kernel menganggap file itu skrip teks biasa — dan bisa jadi dijalankan dengan shell yang salah.
CRLF dari Windows (paling jebakan). File yang dibuat Notepad/editor Windows berakhir dengan \r\n, sedangkan Linux memakai \n. Akibatnya baris pertama jadi #!/bin/bash\r — interpreter "tidak ditemukan" dan setiap baris error $'\r': command not found. Perbaiki dengan:
dos2unix skrip.sh
# atau tanpa dos2unix:
sed -i 's/\r$//' skrip.shMenjalankan skrip yang men-set environment dengan ./ padahal ingin source. Seperti yang kita buktikan: export di dalam skrip yang dijalankan sebagai program hilang begitu selesai. Jika ingin variabel bertahan, gunakan source.
Mengetik bash skrip.sh padahal shebangnya #!/usr/bin/env bash dan isinya fitur BASH. Tidak masalah selama BASH yang dipanggil — tapi kebiasaan ini bisa menutupi masalah interpreter di sistem lain. Biasakan memanggil lewat ./skrip.sh agar shebang yang bekerja.
cat -A skrip.sh#!/bin/bash^M$
echo "Halo"^M$Tanda ^M di akhir baris adalah jejak CRLF dari Windows — petunjuk visual paling jelas kenapa skrip "error aneh".
Warning
Ketika skrip error $'\r': command not found atau interpreter "tidak ditemukan" meski shebang tampak benar, kecurigaan pertama adalah CRLF. Jalankan cat -A skrip.sh dan cari ^M. Ini salah satu bug paling umum yang menyerang semua pemula — dan sekarang kalian tahu cara mengalahkannya.
Pada episode 2 ini kalian telah menulis skrip BASH pertama dan memahami tiga fondasi yang akan menemani kalian selamanya: shebang sebagai identitas interpreter (dengan pilihan #!/bin/bash yang deterministik vs #!/usr/bin/env bash yang portabel), chmod +x sebagai kunci agar skrip bisa dieksekusi sebagai program, dan tiga mode eksekusi — ./skrip.sh dan bash skrip.sh yang berjalan di subshell terisolasi, serta source/. yang berjalan di shell saat ini dan membuat perubahan bertahan.
Inti yang harus kalian bawa:
#!/bin/bash untuk BASH murni.chmod +x diperlukan agar ./skrip.sh berjalan; bash skrip.sh tidak butuh izin eksekusi../skrip.sh dan bash skrip.sh berjalan di subshell — perubahan variabel tidak bertahan.source skrip.sh berjalan di shell saat ini — variabel, cd, dan export bertahan.$'\r' / interpreter tidak ditemukan = file ber-CRLF dari Windows.Sekarang kalian tahu cara menulis dan menjalankan skrip. Di episode 3 selanjutnya kita akan memasuki bahasa BASH itu sendiri: pengenalan dan penjelasan variables & environment variables — aturan penamaan, perbedaan $VAR dan ${VAR}, export untuk mewariskan ke proses anak, variabel bawaan seperti $PATH, $HOME, $USER, hingga membangun skrip yang membaca environment dengan benar. Di situlah kalian mulai "berbicara" dengan BASH, bukan sekadar memerintahkannya. Sampai jumpa!