25 poin oleh GN⁺ 2026-02-28 | 1 komentar | Bagikan ke WhatsApp
  • 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

 
GN⁺ 2026-02-28
Komentar Hacker News
  • Dari sudut pandang API syscall Unix, 2>&1 memiliki arti yang sama dengan dup2(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 seperti 2<1, itu adalah interpretasi yang salah dari sisi makna I/O

    • Saat mencari “dup2(2, 1)” di Safari iPhone, thread ini muncul di hasil kedua
      Letaknya di antara dokumentasi man7 dup2 dan dokumentasi Arch Linux dup2
      Mengejutkan bahwa bot juga membaca ini
    • Mungkin inilah alasan banyak orang merasa bahasa shell POSIX tidak nyaman digunakan
      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
    • Aplikasi menarik dari cara ini adalah menyiapkan file descriptor yang belum diinisialisasi
      >&1 echo "stdout"
      >&2 echo "stderr"
      >&3 echo "fd 3"
      ./foo.sh 3>&1 1>/dev/null 2>/dev/null
      
      Dengan cara ini, kita bisa menyisakan hanya output tertentu dan membisukan sisanya
      Namun, jika tidak dibuka sebelumnya akan muncul error “Bad file descriptor”
    • Saat shell menjalankan program, ia selalu melakukan fork
      redirection menggunakan dup sebelum exec, dan pipe memakai dua kali fork serta syscall pipe
      Manual BASH sangat bagus, jadi sebaiknya lihat dokumentasi resminya
    • Ada konsistensi yang kuat antara API Unix, C, shell, dan Perl
      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

    • Tentu saja, hanya sedikit orang yang tahu harus mencari ke mana
      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
    • Namun sekarang pencarian Google sudah tidak berguna
      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>&1 dan bukan &2>&1 adalah karena & hanya berarti file descriptor dalam konteks redirection
    Menarik bahwa PowerShell juga mempertahankan sintaks yang sama

    • PowerShell memiliki 7 stream: Success, Error, Warning, Verbose, Debug, Information, Progress
      Tautan dokumentasi resmi
    • Namun PowerShell meminjam sintaksnya tetapi merusak semantiknya
      Urutan 2>&1 > file berlawanan dengan Unix sehingga hasilnya tidak seperti yang dimaksud
      Sebelum versi 7.4 juga ada masalah kerusakan byte stream
      Dokumentasi terkait
    • Angka di depan > menentukan file descriptor mana yang akan di-redirect
      >foo sama dengan 1>foo
      Jika ditulis seperti 2>>&1, maka yang tercipta adalah nama file 1, jadi tidak ada maknanya
    • Sebenarnya tidak ada alasan untuk bingung
      > berarti stdout, 2> berarti stderr, dan &1 berarti stdout
    • file1>file2 juga tidak simetris
      /dev/stderr>/dev/stdout adalah padanan yang lebih langsung
  • Penjelasan Claude adalah yang paling mudah dipahami
    2>&1 berarti “kirim output error ke tempat yang sama dengan output biasa”

    • 2 adalah output error, > berarti “kirim”, dan &1 berarti “ke tempat stdout saat ini diarahkan”
    • Agar lebih akurat, 2 berarti file descriptor 2, > berarti penetapan, dan &1 berarti file descriptor 1
    • Namun penjelasan seperti ini pada dasarnya hampir sama dengan jawaban kedua di Stack Overflow (jawaban dbr)
      Dibanding 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

    • Setelah 2025, nostalgia terhadap “masa lalu yang indah” tiba-tiba membesar
      Namun bahkan pada masa itu juga banyak gatekeeping dan suasana sinis
      Kolaborasi yang berpusat pada manusia tidak selalu romantis
    • Dulu saya suka jawaban AI yang ringkas tanpa basa-basi
      Langsung menyampaikan inti tanpa pengantar yang tidak perlu
    • Mencari dulu sebelum bertanya adalah etika dasar :)
    • Saya tidak setuju dengan pernyataan “lebih baik bertanya kepada manusia”
      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 posisinya
    Seperti 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 redirection
    Pola 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

    • Namun pada masa itu pengguna adalah programmer
    • Untuk tujuan output, nama sebenarnya bisa dipakai. & berfungsi memberi tahu bahwa itu bukan file melainkan descriptor
      < sudah dipakai untuk input redirection sehingga tidak bisa dijadikan pengganti
    • Fakta bahwa alat-alat yang sederhana dan logis seperti ini bertahan selama puluhan tahun sangatlah memberi pelajaran
    • Penulisan seperti 2>/dev/stdout mirip dengan 2>&1, tetapi tidak sepenuhnya sama
      /dev/stdout adalah pendekatan berbasis nama yang lebih akrab
    • Justru saya menyukai kesederhanaan shell yang kuno seperti ini
      Skrip 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)

    • Namun disayangkan tool Unix tidak mendukung file descriptor dengan lebih baik
      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/tcp memang ada, tetapi fiturnya terbatas
    • Meski begitu, istilah “file redirection” agak menyesatkan
      Sebenarnya ini diimplementasikan memakai named pipe, jadi tidak bisa di-seek
      Karena itu Zsh menambahkan sintaks =(command) yang memakai file sementara
  • Saya memahami 2>&1 dengan 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

    • Saat wawancara, saya selalu merujuk ke O’Reilly Essential System Administration
      Tautan buku