- Sintaks pengalihan yang digunakan untuk menggabungkan standard error (stderr) dan standard output (stdout) ke dalam satu stream
- Angka 1 berarti stdout, 2 berarti stderr, dan
& digunakan sebagai penanda bahwa yang dirujuk adalah file descriptor
2>&1 berarti “kirim stderr ke tujuan yang saat ini dituju stdout”, dan hasilnya bisa berbeda tergantung urutan output
- Misalnya,
command >file 2>&1 mengirim kedua stream ke file, tetapi command 2>&1 >file membuat hanya stderr yang tetap berada di konsol
- Sintaks pengalihan inti yang sering dipakai di Bash dan shell POSIX untuk menggabungkan output, menyimpan log, dan pemrosesan pipe
File descriptor dan konsep dasar
- 0, 1, 2 masing-masing berarti stdin, stdout, stderr
- Didefinisikan di
/usr/include/unistd.h
#define STDIN_FILENO 0, #define STDOUT_FILENO 1, #define STDERR_FILENO 2
> adalah pengalihan output, `` adalah menulis file baru, >> adalah menambahkan ke file
- Simbol
& menunjukkan bahwa yang dirujuk adalah descriptor, bukan nama file
- Karena itu,
2>1 mengalihkan ke file bernama “1”, sedangkan 2>&1 menduplikasi stderr ke stdout
Cara kerja 2>&1
2> berarti mengalihkan stderr, dan &1 merujuk ke file descriptor milik stdout
- Hasilnya, stderr diarahkan ke tujuan yang sama dengan stdout
- Contoh:
ls -ld /tmp /tnt >/dev/null 2>&1 → kedua output dibuang ke /dev/null
ls -ld /tmp /tnt 2>&1 >/dev/null → hanya stderr yang tetap di konsol
- Pengalihan diproses dari kiri ke kanan, jadi hasilnya berubah jika urutannya berbeda
Pentingnya urutan pengalihan
command >file 2>&1
- stdout lebih dulu dikirim ke file, lalu stderr diduplikasi ke stdout → kedua stream masuk ke file
command 2>&1 >file
- stderr lebih dulu diduplikasi ke stdout saat ini (konsol), lalu hanya stdout yang dikirim ke file → stderr tetap tampil di konsol
- Bash memproses pengalihan secara berurutan, jadi urutan penulisan perintah harus diperhatikan
Berbagai contoh pengalihan
echo test >file.txt → stdout ke file
echo test 2>file.txt → stderr ke file
echo test 1>&2 → stdout ke stderr
command &>file atau command >&file → stdout dan stderr sama-sama ke file (bentuk singkat Bash)
command 2>&1 | tee -a file.txt → kedua stream ditampilkan sekaligus ke file dan terminal
Penggunaan lanjutan dan fitur setelah Bash 4.0
- Sejak Bash 4.0, output bisa dipisahkan dengan process substitution
ls -ld /tmp /tnt 2> >(sed 's/^/E: /') > >(sed 's/^/O: /')
- stdout dan stderr masing-masing dikirim ke filter yang berbeda
|& adalah bentuk singkat dari 2>&1 |, untuk menggabungkan dua stream lalu mengirimkannya ke pipe
- Opsi
set -o noclobber mencegah penimpaan file yang sudah ada, dan pengecualian bisa dilakukan dengan >|
Contoh penggunaan praktis
g++ main.cpp 2>&1 | head → melihat hanya output awal termasuk error kompilasi
perl test.pl > debug.log 2>&1 → menyimpan semua output dan error ke file log
foo 2>&1 | grep ERROR → mencari string “ERROR” di stdout dan stderr sekaligus
docker logs container 2>&1 | grep "some log" → meneruskan seluruh log ke pipe
Ringkasan inti
2>&1 adalah sintaks standar POSIX untuk menduplikasi stderr ke stdout
- Urutan pengalihan menentukan hasil, jadi penulisan perintah harus diperhatikan
- Di Bash,
&> bisa dipakai untuk menangani dua stream sekaligus, dan
ini sangat penting dalam berbagai skrip otomatisasi untuk pengelolaan log, pemrosesan pipe, dan penggabungan error
1 komentar
Komentar Hacker News
Dari sudut pandang API syscall Unix,
2>&1memiliki arti yang sama dengandup2(1, 2)Di shell Unix klasik, hanya itu maknanya, tetapi di shell modern ada bookkeeping internal tambahan untuk melacak status
redirection dijalankan dari kiri ke kanan secara berurutan, dan operator pipe bekerja melalui kombinasi fork dan dup
Namun, meski intuitif jika
dup2(2, 1)dipahami seperti2<1, itu adalah interpretasi yang salah dari sisi makna I/OLetaknya di antara dokumentasi man7 dup2 dan dokumentasi Arch Linux dup2
Mengejutkan bahwa bot juga membaca ini
Terlalu banyak gula sintaks yang menutupi mekanisme internal
Tidak seperti bahasa seperti Lisp yang memperluas struktur sederhana dengan macro, shell punya aturan sintaks yang rumit dan kurang intuitif
Pada akhirnya, keluhan seperti ini tampaknya lahir dari bentrokan ego antara programmer dan sysadmin
Namun, jika tidak dibuka sebelumnya akan muncul error “Bad file descriptor”
redirection menggunakan dup sebelum exec, dan pipe memakai dua kali fork serta syscall
pipeManual BASH sangat bagus, jadi sebaiknya lihat dokumentasi resminya
Namun di bahasa modern atau bahasa di luar ekosistem Unix, nuansa itu hilang
Pada akhirnya, membaca dokumentasi resmi (RTFM) secara langsung adalah cara yang paling pasti
Manual Bash Redirections
Kebanyakan orang mencari jawaban lewat Google, dan hasil pencarian baru muncul setelah pertanyaan-pertanyaan seperti itu menumpuk
Beragam sudut pandang di Stack Overflow justru lebih membantu bagi pemula
Pengguna biasa jadi sulit menemukan informasi yang diinginkan
Jawaban di Stack Overflow mengekspresikan persis apa yang saya pikirkan, jadi saya kutip apa adanya
Alasannya
2>&1dan bukan&2>&1adalah karena&hanya berarti file descriptor dalam konteks redirectionMenarik bahwa PowerShell juga mempertahankan sintaks yang sama
Tautan dokumentasi resmi
Urutan
2>&1 > fileberlawanan dengan Unix sehingga hasilnya tidak seperti yang dimaksudSebelum versi 7.4 juga ada masalah kerusakan byte stream
Dokumentasi terkait
>menentukan file descriptor mana yang akan di-redirect>foosama dengan1>fooJika ditulis seperti
2>>&1, maka yang tercipta adalah nama file1, jadi tidak ada maknanya>berarti stdout,2>berarti stderr, dan&1berarti stdoutfile1>file2juga tidak simetris/dev/stderr>/dev/stdoutadalah padanan yang lebih langsungPenjelasan Claude adalah yang paling mudah dipahami
2>&1berarti “kirim output error ke tempat yang sama dengan output biasa”2adalah output error,>berarti “kirim”, dan&1berarti “ke tempat stdout saat ini diarahkan”2berarti file descriptor 2,>berarti penetapan, dan&1berarti file descriptor 1Dibanding mendapatkannya dari LLM, lebih efisien langsung mengklik tautannya
Saya jadi merindukan era Stack Overflow ketika kita masih bertanya pada manusia
Tetapi sekarang rasanya sulit kembali ke masa itu
Namun bahkan pada masa itu juga banyak gatekeeping dan suasana sinis
Kolaborasi yang berpusat pada manusia tidak selalu romantis
Langsung menyampaikan inti tanpa pengantar yang tidak perlu
Dengan manusia ada beban sosial seperti sungkan, penilaian, dan rasa kompetitif
LLM memberi respons yang netral dan sopan tanpa beban seperti itu
Perilaku shell itu bergantung pada konteks, jadi arti
&berubah tergantung posisinyaSeperti
IFS=\| read A B C <<< "first|second|third", efeknya berlaku lokal hanya di dalam satu baris&di akhir baris berarti menjalankan di background, sedangkan&di tengah berarti redirectionPola seperti ini memang sulit dikuasai, tetapi pada akhirnya memang harus dipelajari
Ini membuat saya kembali sadar betapa purba sistem yang kita gunakan
Menangani file descriptor sebagai angka rasanya seperti memberikan pointer langsung kepada pengguna
Akan lebih baik jika ada pendekatan berbasis nama
&berfungsi memberi tahu bahwa itu bukan file melainkan descriptor<sudah dipakai untuk input redirection sehingga tidak bisa dijadikan pengganti2>/dev/stdoutmirip dengan2>&1, tetapi tidak sepenuhnya sama/dev/stdoutadalah pendekatan berbasis nama yang lebih akrabSkrip dari 15 tahun lalu masih berjalan apa adanya sampai sekarang
redirection benar-benar fitur yang menarik
Misalnya saya sering memakai process substitution seperti
diff <(seq 1 20) <(seq 1 10)Jika file, stream, dan socket bisa diteruskan langsung ke proses, itu akan jauh lebih kuat
Jika Bash bisa membuka socket secara langsung lalu memberikannya ke program lain, sandboxing juga akan jadi lebih mudah
[^1]:
/dev/tcpmemang ada, tetapi fiturnya terbatasSebenarnya ini diimplementasikan memakai named pipe, jadi tidak bisa di-seek
Karena itu Zsh menambahkan sintaks
=(command)yang memakai file sementaraSaya memahami
2>&1dengan menghafalnya sebagai “2 masuk ke alamat 1”Untuk bacaan yang membahas ‘2>&1’ dan redirection secara mendalam:
Understanding Linux's File Descriptors: A Deep Dive Into '2>&1' and Redirection
Tautan diskusi terkait
Tautan buku