Bagaimana saya bisa mengingat cara menggunakan pengalihan?

40

Saya tahu apa

  program > /dev/null 2>&1 

tidak. Ini mengarahkan ulang output ke /dev/nulldan 2>&1berarti untuk mengarahkan output kesalahan di tempat yang sama di mana output dikirim.

Masalah saya adalah saya selalu harus google karena saya tidak pernah mengingatnya.

Jadi, saya mencoba &2>1, 1>2&, 1>&2... Aku mencoba setiap kombinasi sampai aku google itu ...

Apa trik untuk mengingatnya dengan mudah?

Luc M
sumber
Saya memiliki masalah yang sama, jadi saya melakukannya dengan cara "jauh" - mengarahkan keduanya program 1> /dev/null 2>/dev/null. Namun kadang-kadang Anda perlu mencampur stdoutdan stderrbersama - sama untuk melihat apa yang sebenarnya terjadi - seperti output dari proses kompilasi yang rumit diarahkan ke file. Dalam hal ini, saya akhirnya googling
ivanivan

Jawaban:

20

Output lebih baik daripada kesalahan sehingga lebih dulu (1 vs 2).

>adalah singkatan untuk 'pergi ke'. Di sebelah kiri adalah apa yang ingin saya kirim dan di sebelah kanan adalah tempat saya ingin mengirimnya. Karena 'di mana' adalah (hampir) selalu menjadi file, sesuatu seperti

program > /dev/null 2>1

akan mengalihkan ke file bernama 1. Dengan demikian, ampersand (&)memodifikasi file ke file descriptor.

Sayangnya, saya belum menemukan atau mengembangkan mnemonik saya sendiri, tetapi ketika saya pertama kali belajar * nix, saya menemukan cara logis untuk bekerja dengan baik. Setelah beberapa kali run-through, itu menjadi kebiasaan.

gvkv
sumber
Kalimat pertama Anda tidak masuk akal bagi saya. stdoutadalah file descriptor 1, stderris 2. Jadi, "error" hadir sebelum "output".
Warren Young
Kalimat itu adalah mnemonik untuk mengingat deskriptor file mana stdoutdan stderrmerujuk.
gvkv
Oke, tapi itu masih membingungkan, karena pertanyaan aslinya adalah tentang mencoba mengingat urutan karakter dalam mantra "2> & 1".
Warren Young
9

Satu trik hanya untuk mengingat bahwa 1 = output standar, 2 = kesalahan standar. Begitu:

2>&1= aliran kesalahan standar masuk ke aliran keluaran standar.
1>&2= sebaliknya.

Jika Anda pernah memprogram dalam bahasa mirip-C, mudah untuk mengingat ampersand ( &). Saya memilih untuk menganggapnya sebagai merujuk ke "alamat" deskriptor file yang ada, sehingga Anda tidak mengubah file itu sendiri atau membuat yang baru.

Thronic
sumber
7

Melihatnya &sebagai simpul mungkin membantu: pikirkan tentang apa yang ingin Anda lakukan sebagai mengambil hasil 2, jadi 2>, dan mengikatnya bersama 1, jadi2>&1

Bertrand Lorentz
sumber
2
Saya hanya menghafal ungkapan "dua dan satu". Apakah mnemonik Anda adalah ungkapan atau simpul, memiliki satu akan sangat membantu.
Tim Kennedy
5

Sebenarnya, itu tergantung pada shell apa yang Anda gunakan. Bash biasanya sangat pemaaf dan Anda bisa melakukannya:

program &> file
Kevin Cantu
sumber
5

Mari kita pertimbangkan tiga opsi ini:

program  2>1
program  2>1& 
program  2>&1

Yang pertama mengirim stderr ke nama file "1": setelah semua, bash berharap untuk mengarahkan ulang ke file.

Yang kedua juga mengarahkan ke file yang sama tetapi berjalan programdi latar: itulah yang &seharusnya berarti trailing .

Itu meninggalkan kemungkinan ketiga sebagai satu-satunya yang masuk akal di bash universe untuk mengarahkan ke file menangani.

Bagaimana cara mengingat yang mana di antara 0, 1, 2? Pikirkan tentang menjalankan komputer dari konsol. Pertama, Anda harus mengetikkan sesuatu (0 = stdin). Kemudian, Anda melihat output (1 = stdout). Terakhir dan hanya jika ada kesalahan, Anda melihat stderr (2).

John1024
sumber
1

Gambarlah di wallpaper Anda.

Sekarang, serius, ini dan hal-hal dasar lainnya yang saya selalu lupa, jadi saya menambahkan menu tips cepat ke aplikasi yang saya kembangkan dan yang saya gunakan setiap hari. Anda mungkin ingin mencobanya atau menggunakan sesuatu seperti gnote untuk membuat catatan.

Ubersoldat
sumber
1

Sehubungan dengan bash shell saya menemukan cara terbaik untuk diingat adalah dengan memahami apa yang terjadi.
Jika semua yang ingin Anda lakukan adalah mengingat bagaimana cara mendapatkan perintah yang benar, Anda dapat mencoba

program > /results 2> /results

Itu bagus dan jelas apa yang terjadi dan mudah diingat. yaitu

  • 1 STDOUT akan melakukannya /results
  • 2STDERR juga akan langsung ke/results

masalahnya adalah ini tidak berfungsi seperti yang Anda harapkan. pertimbangkan hal berikut:

mengajukan: /tmp/poem.txt

the quick brown fox jumped over the lazy dog

dan jalankan perintah

grep "brown" /tmp/poem.txt NOT_A_FILE > /tmp/results 2> /tmp/results

kemudian

$ cat /tmp/results
grep: NOT_A_FILE: No such file or directory
 lazy dog

Apa yang terjadi disini?
Pemahaman saya adalah bash setup pengalihan mengarahkan STDERR langsung ke file /tmp/resultsdan karena sifat >yang melakukan 2 hal

  1. biasanya membuat file baru - dalam hal ini peluang telah berlalu karena bash telah melewati rutin ini pada saat output dihasilkan.
  2. masukkan langsung ke awal file. dan tidak menambahkan seperti >>halnya.

Jadi dalam hal ini STDERR, menyisipkan langsung ke awal /tmp/resultsmengesampingkan output dari STDOUT.
Catatan: jika Anda terbiasa >>menambahkan Anda mungkin bisa lolos dengan sintaks ini.
Namun untuk memperbaiki masalah yang Anda butuhkan - bukan untuk mengarahkan ulang STDERR - ke file secara langsung, tetapi untuk menggabungkan output STDERR ke dalam aliran STDOUT, sehingga Anda tidak mendapatkan tabrakan.
Menggunakan operator, 2>&1operator mencapai ini

grep "brown" poem.txt NOT_A_FILE > /tmp/results 2>&1

The &memungkinkan bash untuk membedakan dari sebuah file bernama 1dan 1file descriptor.
Bagi saya pernyataan 2>&1itu sendiri menjelaskan dengan tepat apa yang terjadi - STDERR sedang dialihkan ke STDOUT itu sendiri - dan hanya berakhir /tmp/resultskarena di situlah STDOUT diarahkan (hampir sebagai efek samping).
Berbeda dengan apa yang diklaim oleh banyak pemandu, yaitu yang 2>&1mengirim STDERR ke mana pun STDOUT diarahkan. Jika itu benar - Anda masih akan memiliki masalah penulisan ulang.

Untuk informasi lebih lanjut, lihat - http://mywiki.wooledge.org/BashGuide/InputAndOutput#File_Redirection

rev the_velour_fog
sumber