Perbedaan antara 2> & -, 2> / dev / null, | &, &> / dev / null dan> / dev / null 2> & 1

192

Hanya mencari perbedaan di antara keduanya

  • 2>&-
  • 2>/dev/null
  • |&
  • &>/dev/null
  • >/dev/null 2>&1

dan portabilitas mereka dengan non-Bourne shellsseperti tcsh, mksh, dll

Det
sumber
2
Perhatikan bahwa, sementara mksh mendukung &>kompatibilitas bash GNU, sangat disarankan untuk tidak menggunakan ini, karena penguraian dapat mematahkan semantik skrip POSIX yang ada, dan mksh menonaktifkannya dalam mode POSIX.
mirabilos
Saya juga telah melihat ^ /dev/nullapa fungsinya?
balupton

Jawaban:

241

Untuk latar belakang:

  • a angka 1 = standar keluar (yaitu STDOUT)
  • a angka 2 = kesalahan standar (yaitu STDERR)
  • jika angka tidak diberikan secara eksplisit, maka angka 1 diasumsikan oleh shell (bash)

Pertama mari kita menangani fungsi ini. Untuk referensi, lihat Panduan Script Bash Lanjutan .

Fungsi

2>&-

Bentuk umum dari ini adalah M>&-, di mana "M" adalah nomor deskriptor file. Ini akan menutup output untuk deskriptor file mana pun yang direferensikan, yaitu "M" .

2>/dev/null

Bentuk umum dari ini adalah M>/dev/null, di mana "M" adalah nomor deskriptor file. Ini akan mengarahkan file descriptor, "M" , ke /dev/null.

2>&1

Bentuk umum dari ini adalah M>&N, di mana "M" & "N" adalah nomor deskriptor file. Ini menggabungkan output dari deskriptor file "M" dan "N" menjadi satu aliran.

|&

Ini hanya singkatan untuk 2>&1 |. Itu ditambahkan di Bash 4.

&>/dev/null

Ini hanya singkatan untuk >/dev/null 2>&1. Ini mengarahkan file deskriptor 2 (STDERR) dan deskriptor 1 (STDOUT) ke /dev/null.

>/dev/null

Ini hanya singkatan untuk 1>/dev/null. Ini mengarahkan file descriptor 1 (STDOUT) ke /dev/null.

Portabilitas ke non-bash, tcsh, mksh, dll.

Saya belum banyak berurusan dengan kerang lain di luar cshdan tcsh. Pengalaman saya dengan 2 orang itu dibandingkan dengan operator pengalihan bash, adalah bahwa bash lebih unggul dalam hal itu. Lihat halaman manual tcsh untuk lebih jelasnya.

Dari perintah yang Anda tanyakan tidak ada yang secara langsung didukung oleh csh / tcsh. Anda harus menggunakan sintaks yang berbeda untuk membangun fungsi yang sama.

slm
sumber
Kami punya pemenang. Tapi jadi tidak ada perbedaan kinerja atau semacamnya dengan 2>&-vs 2>/dev/null(selain itu beberapa program yang ditulis dengan "buruk" tidak membatalkan 2>&-dengan benar)?
Det
3
Seharusnya tidak ada perbedaan kinerja.
slm
5
&>sudah bashsejak awal (dan istirahat kompatibilitas Bourne dan POSIX karena itu berarti sesuatu yang berbeda di sana, meskipun tidak mungkin untuk dipukul). >&dan |&berasal dari (t)csh(dan itu satu-satunya cara mereka untuk mengarahkan stderr). Mereka masuk zshdari awal dan hanya ditambahkan baru-baru ini ke bash. Lihat juga rcuntuk operator yang dirancang lebih baik.
Stéphane Chazelas
1
Pembaruan: tentang masalah kinerja, itu juga dikonfirmasi di sini: unix.stackexchange.com/questions/163955/…
Det
1
Hai @slm, terima kasih untuk kontaknya. Saya senang repo saya tidak berubah (+2-2=0). Sekarang, ke bagian edisi, saya tidak mengedit banyak, tetapi dalam hal ini saya akan, karena itu menjelaskan bahwa data setelah operasi akan berada di N. Saya sudah membaca jawaban Anda, dan sangat baik dalam semua aspek. Ketidakjelasan kecil ini membuat saya berpikir, itu sebabnya edisi ini. Tapi ok, jangan ragu untuk menambahkan kembali atau menolaknya, seperti yang Anda mau. Saya harap saya bisa menjelaskan maksudnya. Terus bekerja dengan baik.
Dr Beco
11

Ini untuk mengarahkan kembali STDERR & STDOUT:

  • 2>/dev/null

    Redirect STDERR ke / dev / null (mencegah agar tidak muncul di konsol)

  • |&

    Redirect STDERR dan STDOUT ke STDIN dari perintah piped (cmd1 | & cmd2)

  • &>/dev/null

    Redirect STDERR & STDOUT ke / dev / null (tidak ada yang muncul di konsol)

  • >/dev/null

    Redirect STDOUT ke / dev / null (hanya STDERR yang ditampilkan di konsol)

  • 2>&-

    Apakah untuk menutup deskriptor file yang digunakan dengan pengalihan

Ini semua adalah metode pengalihan standar untuk kulit Bourne.

BriGuy
sumber
4
|&dan &>/dev/nullyang tidak portabel.
Chris Down
4

Anggap ini sebagai tambahan untuk jawaban yang dipilih. Anda mungkin ingin tahu formulir mana yang POSIX dan mana yang tidak.

Dua formulir POSIX terlibat:

2.7.2 Mengarahkan Output

Dua format umum untuk mengarahkan output adalah:

[n]> kata

[n]> | kata

di mana opsional n menunjukkan nomor deskriptor file. Jika nomor dihilangkan, pengalihan harus mengacu pada output standar (file deskriptor 1).

Redirection output menggunakan format '>' akan gagal jika opsi noclobber diatur (lihat deskripsi set -C) dan file yang dinamai dengan perluasan kata ada dan merupakan file biasa. Jika tidak, pengalihan menggunakan '>' atau "> |" format akan menyebabkan file yang namanya dihasilkan dari perluasan kata yang akan dibuat dan dibuka untuk output pada deskriptor file yang ditunjuk, atau output standar jika tidak ada yang ditentukan. Jika file tidak ada, itu harus dibuat; jika tidak, itu akan dipotong menjadi file kosong setelah dibuka.

-

2.7.6 Menggandakan Penjelasan File Keluaran

Operator pengalihan:

[n]> & kata

harus menduplikasi satu deskriptor file output dari yang lain, atau akan menutup satu. Jika kata mengevaluasi satu atau lebih digit, deskriptor file dilambangkan dengan n, atau output standar jika n tidak ditentukan, harus dibuat menjadi salinan deskriptor file yang dilambangkan dengan kata; jika digit dalam kata tidak mewakili deskriptor file yang sudah terbuka untuk output, kesalahan pengalihan akan terjadi; lihat Konsekuensi Kesalahan Shell. Jika kata dievaluasi menjadi '-', deskriptor file n, atau output standar jika n tidak ditentukan, ditutup. Upaya untuk menutup deskriptor file yang tidak terbuka tidak akan menyebabkan kesalahan. Jika kata mengevaluasi sesuatu yang lain, perilaku tersebut tidak ditentukan.

Karena itu:

Function      POSIX-compat    POSIX 
2>&-          Yes             close 
2>/dev/null   Yes             redir
2>&1          Yes             dup 
|&            No              
&>/dev/null   No
>/dev/null    Yes             redir
>&/dev/null   ?               ?dup

Baris terakhir tidak ada dalam pertanyaan awal, tetapi bekerja tanpa keluhan di bash. (Juga berfungsi dengan / dev / tty yang diganti dengan / dev / null).

Craig Hicks
sumber
1
Saya selalu ingin tahu lebih banyak.
Det