Redirection adalah mekanisme shell untuk mengarahkan aliran masukan dan keluaran sebuah perintah ke tujuan lain, misalnya berkas di disk atau perangkat khusus yang membuang data. Topik ini membahas operator >, >>, <, 2>, 2>&1, dan /dev/null beserta perilakunya terhadap tiga aliran standar. Setelah membacanya, keluaran perintah dapat disimpan ke berkas, pesan error dapat dipisahkan dari keluaran biasa, dan aliran tertentu dapat dibungkam.
Tiga aliran standar#
Setiap perintah yang dijalankan di terminal memiliki tiga aliran data standar yang dibuka oleh shell sebelum perintah itu berjalan. Aliran masukan standar stdin (standard input, masukan standar) membawa data yang dibaca perintah, aliran keluaran standar stdout (standard output, keluaran standar) membawa hasil kerja perintah, dan aliran error standar stderr (standard error, error standar) membawa pesan error serta diagnostik. Ketiganya diberi nomor agar dapat dirujuk secara langsung.
| Aliran | Nomor | Tujuan bawaan | Isi tipikal |
|---|---|---|---|
| stdin | 0 | papan ketik | data yang dibaca perintah |
| stdout | 1 | layar terminal | hasil kerja perintah |
| stderr | 2 | layar terminal | pesan error dan peringatan |
Nomor ini penting karena redirection bekerja pada aliran, bukan pada perintahnya. Shell menghubungkan aliran yang diminta ke berkas atau perangkat tujuan sebelum perintah dijalankan, sehingga perintah itu sendiri tidak perlu tahu keluarannya ditulis ke layar, ke berkas, maupun ke perintah lain. stderr dipisahkan dari stdout dengan sengaja: hasil kerja dan pesan error dapat diarahkan ke tempat yang berbeda tanpa saling mencampur.
Menyimpan keluaran dengan > dan »#
Tanda > mengarahkan stdout ke sebuah berkas. Apabila berkas itu belum ada, berkas baru dibuat, sedangkan apabila sudah ada, isinya ditimpa dari awal. Operator >> berperilaku berbeda: keluaran baru ditambahkan di akhir berkas tanpa menghapus isi lama. Contoh berikut menyimpan dua baris catatan ke berkas catatan.txt, lalu menampilkannya kembali.
# menyiapkan folder kerja
mkdir -p /tmp/kerja-redirection
cd /tmp/kerja-redirection
# menyimpan keluaran standar ke berkas
printf 'Baris pertama\nBaris kedua\n' > catatan.txt
# menampilkan isi berkas sebagai bukti
cat catatan.txtBaris pertama
Baris keduaBerkas catatan.txt kini tersimpan di disk seolah-olah keluaran itu pernah diketik ke dalamnya. Perhatikan bahwa perintah printf tidak menampilkan apa pun di layar karena stdout-nya telah diarahkan ke berkas. Perilaku penimpaan > ditunjukkan berikut ini.
cd /tmp/kerja-redirection
# tanda > menimpa isi lama tanpa peringatan
printf 'Isi baru yang menggantikan isi lama\n' > catatan.txt
cat catatan.txtIsi baru yang menggantikan isi lamaMemisahkan pesan error dengan 2>#
Perintah yang gagal tetap menghasilkan data, tetapi datanya berupa pesan error yang dikirim melalui stderr, bukan stdout. Berikut ini adalah perintah ls terhadap berkas yang tidak ada. Pesan errornya tetap tampil di layar karena stderr memakai tujuan bawaan yang sama dengan stdout.
cd /tmp/kerja-redirection
# perintah yang gagal tetap menampilkan pesan di layar
ls /tidak-adals: cannot access '/tidak-ada': No such file or directoryKarena stderr memiliki nomor aliran 2, pesan error dapat diarahkan ke berkas dengan 2>. Pada contoh berikut, layar tidak menampilkan apa pun ketika ls gagal, sedangkan pesannya tersimpan utuh di berkas error.txt.
cd /tmp/kerja-redirection
# mengalihkan pesan error ke berkas, layar tetap bersih
ls /tidak-ada 2> error.txt
# pesan error kini berada di dalam berkas
cat error.txtls: cannot access '/tidak-ada': No such file or directoryPemisahan ini berguna ketika keluaran biasa dan pesan error perlu diperlakukan berbeda, misalnya menyimpan hasil pencarian ke satu berkas sementara semua pesan error dikumpulkan ke berkas lain.
Menggabungkan aliran dengan 2>&1#
Notasi 2>&1 mengarahkan aliran 2 mengikuti tujuan aliran 1 pada saat itu. Karakter & menandakan bahwa 1 di sini adalah nomor aliran, bukan nama berkas. Dengan menulis > laporan.txt 2>&1, stdout diarahkan ke berkas lebih dahulu, kemudian stderr mengikuti tujuan yang sama, sehingga keduanya tergabung dalam satu berkas.
cd /tmp/kerja-redirection
# menggabungkan stdout dan stderr ke satu berkas yang sama
ls /tidak-ada > laporan.txt 2>&1
cat laporan.txtls: cannot access '/tidak-ada': No such file or directoryRangkaian pengalihan yang sama dapat diperluas ke bentuk lain, misalnya >> laporan.txt 2>&1 yang menambahkan kedua aliran ke akhir berkas alih-alih menimpanya. Prinsipnya tetap sama, yaitu urutan pembacaan dari kiri ke kanan menentukan arah masing-masing aliran pada saat notasi itu dibaca shell. Selama urutan itu dijaga, penggabungan berfungsi sama baik untuk satu perintah maupun untuk ujung sebuah rangkaian pipe.
Membuang keluaran dengan /dev/null#
Berkas /dev/null adalah berkas khusus yang menerima data apa pun dan segera membuangnya, sehingga tidak pernah penuh dan tidak menyisakan jejak. Pengalihan 2> /dev/null sering dipakai untuk membungkam pesan error yang memang tidak diinginkan, sedangkan > /dev/null membuang keluaran biasa. Contoh berikut menjalankan perintah yang gagal tanpa menampilkan pesannya, lalu memeriksa kode kembali perintah tersebut.
cd /tmp/kerja-redirection
# membuang pesan error ke /dev/null
ls /tidak-ada 2> /dev/null
# mencetak kode kembali perintah terakhir
echo "kode kembali: $?"kode kembali: 2Kode kembali 2 berasal dari ls, yang melaporkan kegagalan meskipun pesannya sudah dibuang. Perilaku ini menunjukkan bahwa redirection hanya mengarahkan data, sedangkan status keberhasilan perintah tetap dilaporkan seperti biasa.
Mengisi masukan dari berkas dengan <#
Tanda < bekerja pada arah sebaliknya, yaitu menghubungkan stdin perintah ke isi sebuah berkas. Perintah yang biasanya menunggu ketikan dari papan ketik kini membaca berkas tersebut seolah-olah datanya diketik langsung. Contoh berikut mengurutkan isi buah.txt dengan sort, lalu menghitung jumlah barisnya dengan wc -l, keduanya melalui masukan berkas.
cd /tmp/kerja-redirection
# menyiapkan berkas masukan
printf 'durian\nalpukat\njeruk\n' > buah.txt
# mengurutkan isi berkas melalui stdin
sort < buah.txt
# menghitung baris melalui stdin
wc -l < buah.txtalpukat
durian
jeruk
3Terdapat perbedaan mekanisme antara sort < buah.txt dan sort buah.txt. Pada bentuk pertama, shell membuka berkas dan menghubungkannya ke stdin, sedangkan pada bentuk kedua, nama berkas diberikan sebagai argumen dan sort membukanya sendiri. Hasilnya sering sama, tetapi perintah yang hanya membaca stdin membutuhkan bentuk <, sehingga pengalihan ini tetap wajib dikuasai.
Kesalahan umum#
Kesalahan pertama adalah menulis 2>&1 sebelum pengalihan berkas. Karena shell membaca dari kiri ke kanan, notasi 2>&1 > berkas menyalin arah aliran 2 pada saat aliran 2 masih menunjuk ke layar, kemudian baru stdout diarahkan ke berkas. Akibatnya pesan error tetap tampil di layar dan berkasnya kosong.
cd /tmp/kerja-redirection
# urutan yang keliru: stderr tidak ikut masuk berkas
ls /tidak-ada 2>&1 > laporan-salah.txt
# berkasnya ternyata tidak berisi apa-apa
wc -c laporan-salah.txtls: cannot access '/tidak-ada': No such file or directory
0 laporan-salah.txtKesalahan kedua adalah memakai > pada berkas yang sudah berisi padahal isinya ingin dipertahankan. Isi lama hilang seketika karena > selalu memotong berkas dari awal, sedangkan >> menambahkan di akhir. Kesalahan ketiga adalah menganggap pengalihan berlaku untuk perintah sesudahnya. Setiap pengalihan melekat pada satu perintah saja, sehingga perintah berikutnya perlu pengalihannya sendiri apabila masih ingin diarahkan ke berkas yang sama.
Ringkasan#
- Setiap perintah memiliki tiga aliran standar: stdin bernomor 0, stdout bernomor 1, dan stderr bernomor 2.
>menyimpan stdout ke berkas dan menimpa isinya, sedangkan>>menambahkan di akhir berkas, dan<mengisi stdin dari sebuah berkas.2>memisahkan pesan error ke berkas sendiri,2>&1menggabungkan arah aliran 2 mengikuti aliran 1, dan/dev/nullmembuang data apa pun.- Rangkaian pengalihan dibaca dari kiri ke kanan, sehingga bentuk yang benar untuk menggabungkan aliran ke satu berkas adalah
> berkas 2>&1.
Referensi#
- Bash Reference Manual: Redirections — GNU Project
— Dokumentasi resmi shell bash mengenai tanda
>,>>,<,2>,2>&1, serta urutan pembacaan pengalihan.