Memahami tiga stream I/O standar Linux — stdin, stdout, stderr — beserta operator redirection (>, >>, 2>, &>), pipeline (|), dan tee untuk membangun rantai perintah yang fleksibel dan menyelamatkan log.

Setelah di episode 4 sebelumnya kita membahas cara membaca, melihat, dan mengedit file teks — mulai dari cat, less, head, tail -f untuk memantau log real-time, sampai editor CLI nano dan vim — pada episode kali ini kita akan membahas salah satu konsep yang membedakan Linux dari sistem operasi lain: I/O streams, redirection, dan pipeline.
Kenapa konsep ini penting? Karena hampir semua pekerjaan administrasi Linux — mulai dari membaca log, menyimpan hasil perintah, sampai merangkai beberapa perintah menjadi satu rantai — bertumpu pada kemampuan kalian mengarahkan aliran data. Tanpa memahami ini, kalian hanya akan mengetik perintah satu per satu dan menyalin output secara manual. Dengan memahaminya, kalian bisa membangun workflow yang otomatis dan efisien.
Di episode ini kita akan membahas empat hal: pertama, tiga stream standar yang selalu menyertai setiap proses; kedua, operator redirection untuk menyimpan dan mengarahkan output; ketiga, pipeline (|) untuk menggabungkan perintah dan tee untuk menampilkan sekaligus menyimpan; keempat, studi kasus nyata merangkai semua konsep untuk membangun laporan sistem.
Setiap program yang berjalan di Linux memiliki tiga "pipa" default yang menghubungkannya dengan lingkungan sekitarnya. Tiga pipa ini disebut stream standar, dan masing-masing memiliki file descriptor (fd) berupa angka:
| Stream | File Descriptor | Arah | Fungsi |
|---|---|---|---|
stdin | 0 | Masuk | Input yang dibaca program (biasanya keyboard) |
stdout | 1 | Keluar | Output normal dari program (hasil yang diinginkan) |
stderr | 2 | Keluar | Output error / diagnostic (pesan kesalahan) |
Analoginya seperti restoran: pelanggan memesan lewat meja (stdin), dapur mengeluarkan hidangan lewat pintu layanan (stdout), dan jika ada keluhan koki, pesan itu keluar lewat jalur terpisah (stderr). Dua jalur keluar yang terpisah ini bukan tanpa alasan — kalian sering ingin menyimpan hasil sukses ke file sementara error ditampilkan di layar, dan dengan pemisahan ini, keduanya bisa diarahkan secara independen.
Mari kita lihat perbedaannya secara nyata. Perintah ls berikut bekerja normal, tapi perintah kedua sengaja dibuat gagal:
ls /home
ls /tidak_ada/home
ls: cannot access '/tidak_ada': No such file or directoryPerhatikan: baris pertama adalah stdout (hasil nyata), sedangkan baris kedua adalah stderr (pesan error). Keduanya tampil di terminal karena secara default terminal menampilkan keduanya — tetapi secara teknis mereka lewat jalur yang berbeda, dan inilah yang akan kita manfaatkan lewat redirection.
Note
Kenapa stderr tidak sekadar digabung ke stdout? Karena dalam automation, kalian sering ingin "membuang" error atau memisahkannya ke file log tersendiri. Bayangkan skrip yang menghasilkan 1000 baris output dan 10 baris error — jika keduanya tercampur, memfilter error menjadi jauh lebih sulit. Pemisahan jalur adalah desain yang disengaja, bukan kebetulan.
> dan >>Operator > mengarahkan stdout ke sebuah file. Jika file sudah ada, isinya ditimpa (overwrite); jika belum ada, file akan dibuat. Operator >> melakukan hal yang sama, tapi menambahkan (append) ke akhir file.
echo "baris pertama" > log.txt
echo "baris kedua" > log.txt
cat log.txt
echo "baris ketiga" >> log.txtbaris kedua
baris ketigaPerhatikan urutannya: > pertama menulis baris pertama; > kedua menimpa dengan baris kedua; lalu >> menambahkan baris ketiga. Hasil akhir: baris pertama hilang selamanya.
Caution
Operator > bersifat destruktif tanpa konfirmasi. Mengetik ls /var/log > log.txt untuk tujuan "menyimpan", padahal sebenarnya ingin menambahkan, akan menghancurkan isi log.txt sebelumnya. Selalu tanyakan pada diri sendiri: apakah saya ingin menimpa atau menambahkan? Jika ragu, pakai >>. Sering kali setelah kecelakaan ini terjadi, kalian baru sadar bahwa bash tidak mengenal tombol undo.
Selain stdout, kita bisa mengarahkan stderr secara eksplisit dengan 2>. Syntax-nya selalu nomor file descriptor diikuti operator tanpa spasi:
| Operator | Arti |
|---|---|
1> | Redirect stdout ke file (sama dengan >) |
2> | Redirect stderr ke file |
&> | Redirect stdout dan stderr ke file |
2>&1 | Arahkan stderr ke tujuan yang sama dengan stdout |
< | Ambil input dari file, bukan keyboard |
Contoh praktis pemisahan dua stream:
ls /home /tidak_ada 1> hasil.txt 2> error.txt
cat hasil.txt
cat error.txt/home
ls: cannot access '/tidak_ada': No such file or directoryDi sini hasil.txt berisi output sukses saja, sementara error.txt berisi pesan error saja. Inilah pola yang dipakai script untuk mencatat setiap kegagalan ke log audit terpisah.
Kemudian ada operator 2>&1 — perhatikan urutan-nya sangat penting. Ekspresi 1> file 2>&1 berarti: arahkan stdout ke file, lalu arahkan stderr ke "tempat stdout saat ini" (yaitu file). Hasilnya kedua stream tercampur dalam satu file, mirip seperti &>:
ls /home /tidak_ada > gabungan.txt 2>&1
cat gabungan.txt/home
ls: cannot access '/tidak_ada': No such file or directoryImportant
Urutan 2>&1 menentukan ke mana stderr pergi. Tulis cmd > file 2>&1: stdout dan stderr keduanya masuk file. Tetapi jika kalian menulis cmd 2>&1 > file, urutannya terbalik: stderr diarahkan ke terminal (tempat stdout saat itu), baru kemudian stdout diarahkan ke file. Hasilnya error tetap muncul di layar, bukan di file. Aturan emasnya: 2>&1 harus diletakkan setelah redirection stdout yang ingin kalian ikuti.
<Simbol < membalik arah: alih-alih output perintah dikirim ke file, isi file yang dikirim ke dalam perintah sebagai stdin. Banyak perintah yang menerima input dari file sebagai argumen langsung (misalnya wc -l log.txt), sehingga < sering terasa berlebihan — tetapi ada kasus di mana ia wajib, terutama saat perintah dirancang untuk membaca stdin:
wc -l < laporan.txt
sort < laporan.txtContoh paling berguna: memberi input ke skrip interaktif secara non-interaktif. Jika login.sh meminta nama pengguna lewat stdin, kalian bisa menyuplai jawabannya dari file nama.txt dengan ./login.sh < nama.txt. Dengan cara ini, skrip yang seharusnya interaktif bisa dijalankan dalam pipeline otomatis.
|: Merangkai PerintahRedirection menghubungkan perintah dengan file; pipeline menghubungkan perintah dengan perintah. Operator | mengambil stdout dari perintah di sebelah kiri dan menyambungkannya ke stdin perintah di sebelah kanan. Ini adalah komposisi fungsi ala UNIX: A | B berarti "jalankan A, kirim outputnya sebagai input B".
ls -l | wc -lPipeline ls -l | wc -l menghitung jumlah baris output ls -l — bukan menghitung file langsung, tapi menghitung baris yang dicetak (perhatikan bahwa jumlah baris ini satu lebih banyak dari jumlah file karena total ditampilkan di header total). Kuncinya: setiap perintah dalam pipeline berjalan bersamaan, dan data mengalir seperti air di antara mereka.
Pipeline menjadi sangat kuat ketika digabung dengan filter. Contoh nyata dari episode selanjutnya (yang akan kita bahas mendalam di episode 6): mencari proses tertentu:
ps aux | grep nginxIni membaca seluruh daftar proses (ps aux), lalu menyaring baris yang mengandung kata nginx (grep). Pola ps aux | grep <nama> adalah salah satu pipeline paling sering dipakai administrator Linux di dunia.
tee: Menampilkan Sekaligus MenyimpanAda situasi di mana kalian ingin output tetap terlihat di terminal sekaligus tersimpan ke file. Operator > memaksa memilih salah satu. Solusinya: perintah tee — analogi namanya: seperti huruf T yang membagi satu aliran menjadi dua. tee membaca stdin, menuliskannya ke file, dan meneruskannya ke stdout:
ls -l | tee hasil-dir.txtOutput ls -l tetap muncul di layar, sementara salinan lengkapnya masuk ke hasil-dir.txt. Tambahkan -a untuk mode append:
Opsi tee | Fungsi |
|---|---|
| (tanpa opsi) | Menimpa file |
-a | Menambahkan ke akhir file |
-i | Mengabaikan sinyal interrupt |
tee paling berguna untuk logging: saat kalian menjalankan proses panjang dan ingin mengamati progresnya secara langsung sambil tetap merekam semua output untuk audit.
Sekarang mari kita rangkai semua konsep dalam satu skenario nyata: membangun laporan penggunaan disk dan memisahkan error ke log.
df -h > /var/log/disk-report.txt 2>> /var/log/disk-error.log && echo "Laporan disimpan" >> /var/log/disk-report.txtdf -h (disk free) menulis ringkasan penggunaan disk ke file laporan, sementara jika ada error (misalnya karena direktori tidak bisa diakses), error tersebut ditambahkan ke log error yang terpisah — tidak mencampuri laporan bersih. Perhatikan penggunaan &&: perintah setelahnya hanya berjalan jika df -h berhasil (exit status 0).
Untuk kasus pipeline yang lebih kompleks, misalnya mengambil lima proses paling boros memori dan menyimpannya:
ps aux --sort=-%mem | head -5 | tee top5-proses.txtDi sini tiga konsep bertemu: pipeline (ps aux | head), filter (head), dan tee untuk menyimpan hasil.
sudo dan Urutan RedirectionIni salah satu kesalahan paling sering yang membuat admin bingung. Coba jalankan:
sudo echo "isi baru" > /etc/hosts
sudo tee /etc/hosts > /dev/null <<< "isi baru"Perintah pertama gagal dengan Permission denied — mengapa? Karena redirection > /etc/hosts dilakukan oleh shell kalian, bukan oleh sudo. Urutan kejadiannya: shell membuka file /etc/hosts untuk ditimpa sebelum sudo dijalankan, dan karena shell kalian berjalan sebagai user biasa, akses ditolak. sudo hanya berlaku untuk perintah echo, bukan untuk pembukaan file oleh shell.
Solusinya adalah membalik tanggung jawab: gunakan sudo tee, di mana tee (yang berjalan sebagai root) yang membuka dan menulis file:
echo "isi baru" | sudo tee /etc/hostsTip
Aturan praktis untuk menulis file yang butuh root: sudo tee. Pola perintah | sudo tee file atau echo "..." | sudo tee -a file untuk append. Dengan cara ini, proses yang membuka file adalah tee yang berjalan dengan hak root — dan kalian masih bisa memakai pipeline di sebelah kiri. Ini pola yang dipakai para admin Linux profesional setiap hari.
| Kesalahan | Gejala | Solusi |
|---|---|---|
Menimpa file penting dengan > | Isi file lama hilang permanen | Selalu pikirkan >>; backup dengan cp bila perlu |
cmd 2>&1 > file (urutan salah) | Error tetap muncul di layar, tidak masuk file | Tulis > file 2>&1 — 2>&1 setelah redirection stdout |
sudo echo ... > /etc/... | Permission denied meski memakai sudo | Pakai sudo tee (lihat callout di atas) |
Lupa bahwa > menimpa file yang berisi log lama | Log audit hilang, jejak terhapus | Gunakan >> untuk log, atau rotasi dengan logrotate |
| Menganggap semua output terminal adalah stdout | Error tercampur ke laporan "bersih" | Pahami stderr (fd 2) dan pisahkan dengan 2>> |
Spasi dalam 2 > file | Bash mengartikan sebagai argumen, bukan redirection | Tulis 2> tanpa spasi di antara nomor fd dan operator |
Pada episode 5 ini, kita telah membongkar fondasi komunikasi antarproses di Linux: tiga stream standar (stdin fd 0, stdout fd 1, stderr fd 2), operator redirection (>, >>, 2>, &>, 2>&1, <), pipeline | untuk merangkai perintah, dan tee untuk menampilkan sekaligus menyimpan output.
Inti yang harus dibawa pulang:
2>&1 harus diletakkan setelah redirection stdout yang ingin diikuti.sudo tidak berlaku untuk redirection shell — gunakan sudo tee saat menulis file root.> menimpa tanpa konfirmasi — selalu pertimbangkan >> untuk log.Kemampuan merangkai perintah ini baru terasa kekuatannya ketika digabung dengan perintah pemrosesan teks. Di episode 6 selanjutnya, kita akan membahas Text Processing & Filtering Commands — menguasai grep, sort, uniq, cut, wc, tr, sed, dan awk untuk menyaring, mengubah, dan mengekstrak data dari teks, termasuk studi kasus nyata: mem-parsing log akses web server untuk menemukan IP paling sering mengunjungi situs kalian. Pastikan tetap semangat, karena setelah episode ini kalian akan bisa "membaca" isi file log sebesar apapun!