Setelah rangkaian perintah dapat diketik dengan lancar di terminal, langkah berikutnya adalah menyimpan rangkaian itu ke dalam berkas sehingga dapat dipanggil ulang tanpa diketik ulang. Topik ini membahas cara menyusun skrip bash pertama, mulai dari baris shebang, pemberian izin eksekusi melalui chmod, hingga dua cara menjalankan berkas skrip, yaitu eksekusi sebagai program dan sourcing ke dalam shell yang sedang berjalan. Pekerjaan kecil yang sering diulang dapat disimpan sebagai satu berkas yang cukup dipanggil kapan pun dibutuhkan.
Dari perintah interaktif ke skrip#
Skrip paling baik ditulis untuk pekerjaan yang sudah dapat dikerjakan secara manual. Rangkaian perintah berikut adalah contohnya, yaitu membuat catatan singkat lalu menghitung jumlah barisnya. Ketik ketiga perintah ini di terminal, satu per satu, kemudian amati keluarannya.
# pekerjaan kecil yang biasa diketik berulang kali di terminal
mkdir -p catatan
printf 'rapat mingguan\nbelanja bulanan\n' > catatan/agenda.txt
wc -l catatan/agenda.txt2 catatan/agenda.txtKeluaran yang muncul persis sama apabila ketiga perintah itu disimpan ke dalam satu berkas dan dijalankan sekali saja. Urutan perintah pada skrip dieksekusi dari atas ke bawah, sebagaimana shell membaca ketikan di terminal. Prinsip ini penting untuk dipegang sejak awal, karena skrip tidak memiliki kemampuan baru yang tidak dimiliki terminal, melainkan hanya menyimpan urutan perintah yang sudah dikuasai.
Keuntungan menyimpan urutan perintah muncul ketika pekerjaan itu diulang. Mengetik ulang tiga perintah masih terkendali, tetapi rangkaian pekerjaan nyata biasanya memuat puluhan perintah dengan argumen yang panjang. Semakin panjang urutannya, semakin besar peluang satu langkah terlewat atau salah ketik. Berkas skrip menyimpan urutan itu sekali saja, sehingga pemanggilan ulang cukup dilakukan dengan satu perintah.
Baris shebang#
Berkas skrip adalah berkas teks biasa yang isinya berupa perintah bash, sehingga dapat dibuat dengan editor teks apa pun. Baris pertamanya memiliki peran khusus dan disebut shebang, yakni pasangan karakter #! diikuti jalur penerjemah yang digunakan saat berkas dijalankan langsung sebagai program. Kernel, yaitu inti sistem operasi, membaca baris ini untuk menentukan program yang mengolah sisa isi berkasnya. Untuk skrip bash, bentuk yang lazim adalah #!/usr/bin/env bash.
Perintah env dipilih alih-alih jalur tetap seperti /bin/bash karena env mencari bash pada variabel PATH sebelum menjalankannya. Dengan cara ini, skrip tetap berjalan pada sistem yang menempatkan bash di lokasi berbeda, misalnya di /usr/local/bin. Perbedaan ini terasa kecil pada satu komputer, tetapi berpengaruh ketika skrip yang sama digunakan di banyak sistem.
Skrip pertama bernama sapa.sh disimpan di samping topik ini dan berisi dua perintah printf. Baris set -euo pipefail pada awal skrip mengaktifkan strict mode, yaitu aturan penanganan error yang lebih ketat, sehingga kesalahan tidak berlanjut tanpa terdeteksi. Rincian opsi tersebut dibahas tuntas pada topik strict mode. Untuk saat ini, baris itu cukup dijadikan kebiasaan tetap pada setiap skrip bash.
#!/usr/bin/env bash
# sapa.sh: skrip bash pertama
set -euo pipefail
printf 'Halo, dunia!\n'
printf 'Skrip pertama berhasil dijalankan.\n'Menjalankan skrip dengan bash#
Cara pertama menjalankan skrip adalah memanggil penerjemahnya secara eksplisit. Perintah bash sapa.sh melahirkan proses bash baru yang membaca isi berkas lalu menjalankannya baris demi baris. Baris shebang pada cara ini hanya dianggap komentar, karena penerjemah sudah ditentukan oleh perintah yang dipanggil. Cara ini dapat digunakan kapan pun tanpa mengubah izin berkas, sehingga sering menjadi pilihan pertama saat skrip sedang dikembangkan. Jalankan perintah berikut dan bandingkan keluarannya dengan urutan interaktif pada bagian sebelumnya.
# panggil penerjemah bash dengan nama berkas sebagai masukannya
bash sapa.shHalo, dunia!
Skrip pertama berhasil dijalankan.Keluarannya sama dengan hasil mengetik dua perintah printf satu per satu. Karakteristik cara ini perlu diperhatikan, yaitu seluruh eksekusi berlangsung di dalam proses bash yang baru lahir. Segala perubahan yang terjadi di dalam skrip, seperti penugasan variabel atau definisi fungsi, hilang bersama proses itu ketika skrip selesai. Setiap pemanggilan membaca berkas dari awal, sehingga hasil suntingan selalu terlihat pada pemanggilan berikutnya. Perilaku ini menjadi dasar pembahasan sourcing pada bagian akhir topik.
Izin eksekusi dengan chmod#
Cara kedua menjalankan skrip adalah memperlakukannya seperti program, yaitu mengetik jalurnya langsung. Kernel menuntut satu syarat sebelum mengizinkan cara ini, yaitu berkas harus memiliki izin eksekusi. Berkas skrip yang baru dibuat biasanya hanya memuat izin baca dan tulis, yaitu -rw-r--r--, sehingga izin eksekusi perlu ditambahkan. Perintah chmod dengan tambahan +x menambahkan izin tersebut, sedangkan izin berkas dapat diperiksa dengan stat -c '%A %n' yang menampilkan izin dan nama berkas.
# tambahkan izin eksekusi, lalu periksa hasilnya
chmod +x sapa.sh
stat -c '%A %n' sapa.sh-rwxr-xr-x sapa.shHuruf x yang muncul pada keluaran menandakan izin eksekusi untuk pemilik berkas, kelompoknya, dan pengguna lain. Setelah izin terpasang, skrip dapat dipanggil langsung. Ketik ./sapa.sh untuk menjalankannya.
# jalankan langsung sebagai program
./sapa.shHalo, dunia!
Skrip pertama berhasil dijalankan.Awalan ./ wajib ditulis dan menunjuk direktori saat ini. Shell tidak mencari program di direktori saat ini, melainkan hanya pada daftar direktori yang tersimpan di variabel PATH. Tanpa awalan tersebut, shell menganggap sapa.sh sebagai nama program yang berada di PATH dan melaporkan bahwa perintahnya tidak ditemukan. Dengan awalan ./, kernel membaca baris shebang lalu menyerahkan berkas kepada bash sesuai isinya.
Eksekusi dan sourcing#
Perintah bash sapa.sh dan ./sapa.sh sama-sama melahirkan proses baru. Cara ketiga, yaitu sourcing, bekerja berbeda, yakni menjalankan isi berkas pada shell yang sedang berjalan tanpa melahirkan proses baru. Perintah source digunakan untuk itu. Perbedaan isolasinya dapat diamati lebih dahulu lewat subshell, yaitu proses salinan yang lahir dari sepasang tanda kurung, dengan demonstrasi berikut.
# subshell menjalankan salinan shell, perubahan tidak mengalir balik
(warna="dalam-subshell"; printf 'di dalam subshell: %s\n' "$warna")
printf 'di shell induk: %s\n' "${warna-belum-ada}"di dalam subshell: dalam-subshell
di shell induk: belum-adaNilai warna hidup hanya di dalam proses salinan dan tidak dikenal pada shell induk. Proses anak yang lahir dari bash sapa.sh berperilaku sama, sehingga variabel maupun fungsi yang didefinisikan di dalam skrip ikut hilang ketika skrip selesai. Perilaku ini menjaga shell interaktif tetap bersih dari efek samping skrip yang dijalankannya.
Kondisi berubah ketika definisi memang dirancang untuk dipakai ulang, misalnya sekumpulan fungsi salam yang disimpan sebagai library, yakni berkas definisi yang dimuat oleh skrip lain. Berkas lib.sh berisi definisi seperti itu. Berkas library tidak wajib memuat shebang karena tidak pernah dijalankan langsung sebagai program, melainkan selalu dimuat oleh shell lain.
# lib.sh: library definisi yang dimuat melalui sourcing
SALAM="Halo"
sapa() {
printf '%s, dunia!\n' "$SALAM"
}Jalankan lib.sh sebagai program anak terlebih dahulu untuk melihat efeknya.
# jalankan lib.sh sebagai program anak
bash lib.shTidak ada keluaran yang muncul dan tidak ada pula yang berubah pada shell yang menjalankan perintah itu. Sekarang muat berkas yang sama melalui sourcing.
# muat definisi ke dalam shell yang sedang berjalan
source lib.shSetelah sourcing, fungsi sapa dan variabel SALAM hidup pada shell yang sedang dipakai dan langsung dapat dipanggil.
# fungsi dari library kini dapat dipanggil
sapaHalo, dunia!# variabel yang didefinisikan di dalam library juga ikut dimuat
printf 'SALAM berisi %s\n' "$SALAM"SALAM berisi HaloKesalahan umum#
Skrip tidak dapat dijalankan langsung dengan pesan Permission denied. Kesalahan ini muncul ketika ./nama.sh diketik padahal izin eksekusi belum diberikan. Kernel menolak menjalankan berkas yang tidak memuat huruf x pada izinnya. Perbaikannya adalah chmod +x nama.sh, atau memanggil skrip melalui penerjemah dengan bash nama.sh, yang tidak menuntut izin eksekusi apa pun.
Shebang tidak berada pada baris pertama. Kernel hanya membaca baris pertama berkas untuk menemukan penerjemahnya. Baris kosong atau komentar di atasnya menggeser shebang dari posisi pertama, sehingga pemanggilan langsung kehilangan acuan penerjemah. Pastikan #!/usr/bin/env bash selalu menjadi baris paling atas, tanpa spasi di depannya.
Mengharapkan efek sourcing dari pemanggilan biasa. Berkas library yang dipanggil dengan bash lib.sh tidak meninggalkan definisi apa pun pada shell yang memanggilnya. Efek itu hanya muncul melalui source, karena hanya sourcing yang menjalankan isi berkas pada shell saat ini. Apabila sebuah fungsi tetap tidak dikenal setelah berkasnya dimuat, periksa apakah berkasnya dimuat dengan source atau hanya dijalankan sebagai program.
Ringkasan#
- Skrip bash adalah urutan perintah yang sama dengan yang diketik di terminal, disimpan dalam berkas teks dan dijalankan dari atas ke bawah.
- Baris shebang
#!/usr/bin/env bashmenyatakan penerjemah yang digunakan kernel saat berkas dijalankan langsung sebagai program. bash nama.shdapat digunakan kapan pun, sedangkan./nama.shmenuntut izin eksekusi darichmod +x.- Eksekusi melahirkan proses baru yang mengisolasi variabel dan fungsi, sedangkan sourcing memuat definisi ke dalam shell yang sedang berjalan.
Referensi#
- GNU Bash Reference Manual — Free Software Foundation — dokumentasi resmi bash untuk aturan pemanggilan shell, ekspansi, dan opsi set.
- The Linux Command Line — William Shotts — bab penulisan skrip pertama yang membahas shebang, izin eksekusi, dan struktur skrip.