← Beranda   |   Pilih materi →

Variabel, loop, dan izin akses

Oleh Agus Wibowo

Gurita Cincin Biru


Daftar isi

Catatan: Dalam tutorial ini, kita akan bekerja menggunakan pemrograman Bash dalam lingkungan Linux. Anda dapat menggunakan VS code baik untuk membuat script bash maupun menjalankan script tersebut via terminal.

Pendahuluan

Dalam tutorial ini, kita akan bekerja dengan dataset dari sebuah studi yang menganalisis transkriptom Gurita Cincin Biru (Hapalochlaena maculosa) dari berbagai jaringan tubuh. Studi ini merupakan bagian dari proyek sekuensing genom Gurita Cincin Biru yang dipublikasikan di Giga Science pada tahun 2020. Proyek tersebut dipimpin oleh mahasiswa doktoral Brooke Whitelaw yang merupakan anggota dari kelompok riset Marine Omics di James Cook University (JCU).

Tutorial ini mencerminkan tahapan umum yang sering dilakukan untuk mengunduh data dari pusat sekuensing. Selain itu, tutorial ini juga memperkenalkan konsep dasar seperti loop dan variabel, yang sangat berguna dalam berbagai konteks, terutama saat bekerja dengan banyak berkas input.

Memahami nama file dan ekstensi

Memahami nama file dan ekstensi

Pusat sekuensing baru saja mengirimkan email yang menginformasikan bahwa data sudah tersedia. Dalam email tersebut, mereka menyebutkan bahwa terdapat 24 berkas terpisah yang siap diunduh. Mengunduh satu per satu tentu akan memakan waktu dan rentan terhadap kesalahan. Untungnya, nama berkas dan URL unduhan mengikuti pola tertentu, sehingga proses ini dapat diotomatisasi.

Dalam proyek nyata, kita sering kali harus menangani ratusan hingga ribuan berkas hasil sekuensing. Oleh karena itu, melakukan proses ini secara manual bukanlah pilihan yang realistis, sehingga otomatisasi menjadi keharusan.

Pusat sekuensing juga memberikan contoh pola URL untuk mengunduh berkas-berkas tersebut, yaitu sebagai berikut:

Contoh format file

Saat kita mengirimkan sampel ke pusat sekuensing, maka kita akan menyertakan kode sampel, misalnya dalam kasus ini berasal dari dua belas jaringan yang diambil dari satu individu hewan (lihat tabel di bawah). Proses sekuensing dilakukan dengan metode paired-end, sehingga untuk setiap sampel akan tersedia dua berkas: satu berkas R1 yang berisi forward reads dan satu berkas R2 yang berisi reverse reads.

Kode Sampel Jaringan
EM1 Kulit bagian dorsal mantel
EM2 Bola mata
EM3 Insang (termasuk kelenjar brankial)
EM4 Jantung brankial
EM5 Apendiks renal
EM6 Jantung sistemik
EM7 Saluran reproduksi jantan (belum matang)
EM8 Kelenjar ludah posterior
EM9 Otot mantel ventral (termasuk kulit)
EM10 Otak
EM11 Kelenjar ludah anterior
EM12 Kelenjar pencernaan

Tugas kita kali ini adalah membuat sebuah skrip sederhana untuk mengunduh seluruh data. Untuk menyelesaikan tugas ini, kita akan mempelajari beberapa konsep baru yang penting. Kita akan membangunnya secara bertahap agar prosesnya mudah diikuti dan dipahami.

Variabel

Variabel adalah penampung sementara untuk menyimpan informasi. Konsep ini digunakan dalam semua bahasa pemrograman, termasuk Bash. Sebagai contoh, kita dapat membuat sebuah variabel bernama sample dan menetapkan nilainya dengan salah satu nama sampel kita, seperti berikut:

# bash
sample="EM1"

Jika kita ingin mengambil kembali nilai yang disimpan dalam sebuah variabel, kita cukup menggunakan operator $. Misalnya untuk menampilkan isi dari variabel sample, kita cukup menuliskan:

# bash
sample="EM1"
echo $sample

Perintah di atas akan mencetak nilai yang tersimpan dalam variabel sample, dalam contoh ini, yaitu EM1.

Perintah echo juga memungkinkan kita untuk menggabungkan variabel dengan teks tetap (fixed strings). Misalnya:

# bash
sample="EM1"
echo $sample
echo "File yang diproses adalah ${sample}_R1.fastq.gz" # _R1.fastq.gz adalah contoh fixed strings

Kemampuan ini sangat berguna saat kita ingin membuat pesan yang informatif selama skrip berjalan, misalnya untuk memantau proses unduhan atau debugging.

Perhatikan penggunaan kurung kurawal {} di sekitar nama variabel pada contoh kedua, seperti ${sample}. Penggunaan kurung kurawal ini penting karena tanpa mereka, interpreter (penerjemah perintah) tidak akan tahu bagian mana dari teks yang merupakan variabel dan mana yang merupakan teks biasa.

Perhatikan bagaimana perintah terakhir di bawah ini menyisipkan isi dari ${sample} ke dalam bagian tertentu dari sebuah string yang lebih panjang. Teknik ini sangat berguna dalam proses otomatisasi, karena kode yang sama dapat menghasilkan string yang berbeda tergantung pada nilai yang disimpan dalam variabel ${sample}. Sebagai contoh:

# bash
sample=EM1
echo "Mengunduh file untuk sampel ${sample}_R1.fastq"

sample=EM2
echo "Mengunduh file untuk sampel ${sample}_R1.fastq"

Output dari perintah-perintah tersebut akan menjadi:

Mengunduh file untuk sampel EM1_R1.fastq
Mengunduh file untuk sampel EM2_R1.fastq

Dengan cara ini, kita bisa menghindari penulisan perintah yang sama berulang kali, dan cukup mengubah nilai variabel untuk memproses banyak file secara otomatis.

Tapi sejauh ini, cara tersebut belum terlalu berguna, bukan? Bayangkan jika kita bisa mengotomatisasi proses pemberian nilai baru ke variabel sample, sehingga secara otomatis bisa memproses seluruh daftar 12 sampel kita. Nah, itu baru benar-benar berguna!

Di sinilah konsep loop (perulangan) mulai berperan.

Loop

Loop memungkinkan kita untuk melakukan tugas yang sama secara berulang dalam konteks yang berbeda, misalnya pada berbagai berkas, nama-nama dalam daftar, kolom dalam sebuah tabel, dan sebagainya.

Hampir semua bahasa pemrograman mendukung konsep perulangan (loop) dalam berbagai bentuk. Di dalam bash, sintaks dasar untuk sebuah for loop adalah seperti ini:

for placeholder in <list>
do
  <commands>
done

Perulangan ini akan mengambil setiap item dalam <list> dan secara sementara menetapkannya ke sebuah variabel yang disebut placeholder. Bagian antara do dan done dapat berisi sebanyak mungkin perintah yang kita butuhkan. Selama perulangan berlangsung, kita bisa menggunakan nilai dari placeholder untuk menjalankan perintah-perintah tersebut.

Sebagai contoh, kita bisa menuliskan seperti ini:

# bash
for sample in EM1 EM2 EM3
do
  echo "Mengunduh file ${sample}_R1.fastq"
  echo "Mengunduh file ${sample}_R2.fastq"
done

Hasil dari skrip ini adalah:

Mengunduh file EM1_R1.fastq
Mengunduh file EM1_R2.fastq
Mengunduh file EM2_R1.fastq
Mengunduh file EM2_R2.fastq
Mengunduh file EM3_R1.fastq
Mengunduh file EM3_R2.fastq

Anda bisa mengekplorasi konsep loop ini sembari menjawab pertanyaan berikut:

  • Apa yang terjadi jika Anda mengubah nama variabel placeholder?
  • Apa yang terjadi jika Anda mengubah item dalam <list>?
  • Apa yang terjadi jika Anda menambahkan lebih banyak atau perintah yang berbeda di antara do dan done?

Aplikasi loop untuk mendownload file sekuen

Pada contoh for loop sebelumnya, kita harus mengetik secara manual semua nama sampel seperti “EM1”, “EM2”, “EM3”, dan seterusnya. Pola yang berulang seperti ini sebenarnya sangat mudah untuk diotomatisasi.

Dalam kasus ini, kita memiliki urutan kode sampel yang hanya berupa angka 1 sampai 12 dengan awalan “EM”. Untuk membuat deretan angka tersebut, kita bisa menggunakan perintah seq di bash.

Sebagai contoh:

# bash
seq 1 3

Perintah di atas akan menghasilkan:

1
2
3

Sering kali, saat kita menjalankan sebuah perintah di terminal, hasilnya akan langsung ditampilkan di layar. Sebelumnya, kita telah melihat bahwa hasil keluaran (output) ini bisa diarahkan ke sebuah berkas menggunakan simbol > (untuk menimpa) atau >> (untuk menambahkan).

Namun, sebagai alternatif lain, keluaran dari sebuah perintah juga bisa ditangkap dan disimpan ke dalam sebuah variabel. Ini dilakukan dengan sintaks berikut:

# bash
variable=$(<command>)

Misalnya:

# bash
angka=$(seq 1 5)
echo "Urutan angka: $angka"

Outputnya:

Urutan angka: 1 2 3 4 5

Output yang telah ditangkap dalam sebuah variabel juga bisa digunakan untuk membuat daftar (list) dalam perulangan. Misalnya, kita bisa membuat sebuah loop untuk mencetak semua nama file yang diinginkan pada 12 sampel yang ada, mulai dari EM1, EM2 EM3, dst secara berurutan.

# bash
samples=$(seq 1 12)
for n in $samples
do
  a="EM${n}"  
  echo "Memproses sampel: EM${a}_R1.fastq.gz"
  echo "Memproses sampel: EM${a}_R2.fastq.gz"
done

Penjelasan:

  • seq 1 12 menghasilkan angka 1 hingga 12.

  • Hasilnya disimpan ke dalam variabel samples.

  • Kemudian, loop for berjalan pada setiap angka dalam variabel tersebut.

  • Di dalam perulangan, kita menyisipkan angka tersebut ke dalam nama sampel menggunakan EM${i}.

Output yang dihasilkan akan berupa:

Memproses sampel: EM1_R1.fastq.gz
Memproses sampel: EM2_R1.fastq.gz
...
Memproses sampel: EM12_R1.fastq.gz

Dengan pendekatan ini, kita dapat menghemat waktu dan menghindari kesalahan pengetikan saat bekerja dengan pola nama yang berulang.

Mendownload file sekuen

wget merupakan perintah yang sangat powerful untuk mengunduh berkas dari internet. wget mendukung berbagai protokol jaringan, metode autentikasi, serta menyediakan banyak opsi untuk menyesuaikan cara kerjanya.

Untuk mendapatkan gambaran seberapa fleksibel dan canggih perintah ini, kita bisa melihat halaman manualnya dengan menjalankan perintah berikut di terminal:

# bash
man wget

Halaman manual ini akan menampilkan seluruh dokumentasi wget, termasuk berbagai opsi yang bisa digunakan seperti melanjutkan unduhan yang terputus, menyimpan berkas dengan nama tertentu, mengatur kecepatan unduh, dan banyak lagi.

Kita akan menggunakan perintah wget untuk mengunduh berkas-berkas sekuensing kita. Karena jumlah berkasnya cukup banyak, sebaiknya kita menatanya dalam direktori khusus agar lebih terorganisir dengan perintah mkdir -p untuk disimpan dalam direktori data/sequencing

# bash
mkdir -p data/sequencing

Option -p disini digunakan untuk membuat folder data/sequencing tanpa menimbulkan error jika folder dengan nama yang sama sudah tersedia.

Sekarang, coba kita download satu berkas saja dengan perintah wget

# bash
wget https://s3-ap-southeast-2.amazonaws.com/bc3203/EM_10k/EM10_R1.fastq.gz -O data/sequencing/EM10_R1.fastq.gz

Catatan: option -O disini digunakan untuk menspesifikasi lokasi tempat kita akan menaruh output hasil download. Tanpa option ini, berkas yang didownload tidak akan disimpan di direktori data/sequencing.

Sampai titik ini, kita bisa mengkombinasikan pemahaman tentang loop dan wget untuk mendownload semua berkas sekuensing (24 berkas) dalam sekali running.

# bash
mkdir -p data/sequencing
for n in $(seq 1 12)
	do 
	s="EM${n}"
	wget https://s3-ap-southeast-2.amazonaws.com/bc3203/EM_10k/${s}_R1.fastq.gz -O data/sequencing/${s}_R1.fastq.gz
	wget https://s3-ap-southeast-2.amazonaws.com/bc3203/EM_10k/${s}_R2.fastq.gz -O data/sequencing/${s}_R2.fastq.gz
done

Mengamankan data sekuen

Data sekuensing umumnya mahal dan memerlukan waktu lama untuk dihasilkan. Seiring berjalannya berbagai analisis, kita akan menghasilkan banyak data turunan (derived data), yaitu hasil dari analisis yang dilakukan. Dengan menggunakan alat seperti Vscode dan menjalankan analisis melalui command line, data turunan ini biasanya bisa diregenerasi dengan cukup mudah.

Namun, data mentah (raw data) hasil sekuensing tidak bisa dibuat ulang begitu saja. Oleh karena itu, setelah mengunduh data mentah, kita selalu disarankan untuk menjadikannya hanya-baca (read-only). Langkah ini membantu melindungi data dari kesalahan seperti menimpanya secara tidak sengaja, atau menghapusnya dengan perintah rm.

Tentu saja, ini bukan perlindungan penuh, membuat salinan cadangan (backup) tetap sangat penting tetapi menjadikan berkas read-only adalah langkah awal yang sangat disarankan.

Semua berkas di sistem Unix memiliki informasi izin akses (permissions) yang mengatur siapa yang bisa membaca, menulis, atau mengeksekusi berkas tersebut. Gambar berikut ini memberikan ringkasan singkat tentang cara kerja sistem izin tersebut:

Contoh format file

Izin akses untuk sebuah berkas dapat dilihat menggunakan perintah ls dengan opsi -l. Perintah ini akan menampilkan daftar berkas dalam format yang lebih rinci, termasuk informasi tentang siapa yang dapat membaca, menulis, atau mengeksekusi berkas tersebut.

Sebagai contoh, untuk melihat izin dari salah satu berkas hasil unduhan, kita bisa menggunakan perintah:

# bash
ls -l data/sequencing/EM1_R1.fastq.gz

Output-nya mungkin akan serupa seperti contoh berikut:

total 56
-rwxr-xr-x@ 1 aguswibowo  staff  25900 12 Jun  2018 EM1_R1.fastq

Perhatikan hasil dari perintah ls -l tersebut. Kemungkinan besar Anda akan melihat bahwa pengguna (user), yaitu Anda sendiri, memiliki izin membaca (r) dan menulis (w) terhadap berkas. Pengguna lain dalam grup yang sama biasanya memiliki izin membaca (r) saja, dan pengguna lain di luar grup juga hanya bisa membaca (r).

Dalam kasus saya, simbol seperti @ ini umum ditemui di macOS, dan digunakan untuk fitur-fitur khusus sistem seperti sandboxing atau metadata. Untuk saat ini, Anda tidak perlu khawatir mengenai hal tersebut.

Perintah chmod digunakan untuk mengubah izin akses pada sebuah berkas. Salah satu cara termudah menggunakan chmod adalah dengan sintaks berikut:

chmod <ugo><+-><rwx> file

Bagian pertama dari sintaks chmod, yaitu ugo, ini menentukan siapa yang akan terpengaruh oleh perubahan izin:

  • u = user (pemilik berkas)

  • g = group (grup pemilik)

  • o = others (pengguna lain di luar user dan grup)

Kita juga bisa menggabungkannya, misalnya:

  • ug berarti perubahan akan diterapkan ke user dan group

Bagian kedua adalah simbol + atau -, yang menunjukkan apakah kita akan menambahkan (+) atau menghapus (-) izin.

Bagian terakhir menunjukkan jenis izin yang akan diubah:

  • r = read (membaca)

  • w = write (menulis)

  • x = execute (menjalankan)

Contoh, kita bisa menghapus akses write dan execute untuk semua user, sebagai contoh berikut:

# bash
chmod ugo-w data/sequencing/EM1_R1.fastq.gz

Cek lagi status hak akses dengan ls -l.

# bash
ls -l data/sequencing/EM1_R1.fastq.gz

Sehingga hasilnya akan seperti contoh berikut:

total 56
-r--r--r--@ 1 aguswibowo  staff  25900 12 Jun  2018 EM1_R1.fastq

— Sekian —

← Beranda   |   Pilih materi →