Dalam shell, apa artinya "2> & 1"?

2285

Di shell Unix, jika saya ingin menggabungkan stderrdan stdoutmasuk ke stdoutstream untuk manipulasi lebih lanjut, saya bisa menambahkan berikut ini di akhir perintah saya:

2>&1

Jadi, jika saya ingin menggunakan headpada output dari g++, saya bisa melakukan sesuatu seperti ini:

g++ lots_of_errors 2>&1 | head

jadi saya hanya bisa melihat beberapa kesalahan pertama.

Saya selalu kesulitan mengingat ini, dan saya harus terus mencarinya, dan itu terutama karena saya tidak sepenuhnya mengerti sintaks dari trik khusus ini.

Dapatkah seseorang memecah ini dan menjelaskan karakter demi karakter apa 2>&1 artinya?

Tristan Havelick
sumber
50
@ dbr Saya tidak berpikir itu hanya bash - Saya percaya itu adalah masalah shell bourne; karenanya sh, bash, ksh, ash, dash, dll.
senjata
8
Ini adalah bagian dari paragraf redirection yang mendeskripsikan shell yang sesuai dengan POSIX, atau singkatnya dengan POSIX. ksh adalah shell POSIX misalnya. Lihat: pubs.opengroup.org/onlinepubs/009695399/utilities/…
jim mcnamara
12
Konstruk ini juga berfungsi pada Windows.
Vadzim
2
Ini umumnya lebih baik 2>&1daripada 2> / dev / null ;-)
F. Hauri
11
Saya pikir saya akan menyebutkan bahwa |& itu singkatan untuk 2>&1 |jika Anda menggunakan zsh. Saya tidak dapat berbicara apakah itu berlaku untuk cangkang mirip bourne lain atau jika itu hanya fitur zsh.
chrixian

Jawaban:

2557

Deskriptor file 1 adalah output standar ( stdout).
Deskriptor file 2 adalah kesalahan standar ( stderr).

Berikut adalah salah satu cara untuk mengingat konstruksi ini (meskipun tidak sepenuhnya akurat): pada awalnya, 2>1mungkin terlihat seperti cara yang baik untuk mengarahkan stderrke stdout. Namun, itu sebenarnya akan ditafsirkan sebagai "redirect stderrke file yang bernama 1". &menunjukkan bahwa yang berikut adalah deskriptor file dan bukan nama file. Jadi membangun menjadi: 2>&1.

Ayman Hourieh
sumber
281
tapi bukankah seharusnya itu terjadi &2>&1?
dokaspar
319
@Dominik: Tidak, &hanya diartikan sebagai "file descriptor" dalam konteks pengalihan. Menulis command &2>&diuraikan sebagai command &dan 2>&1, yaitu "jalankan commanddi latar belakang, lalu jalankan perintah 2dan arahkan stdout ke stdout".
Adam Rosenfield
15
Mengapa mereka memilih barang-barang aneh seperti ini? Hanya penasaran.
CommaToast
81
Tetapi bagaimana Anda mengarahkan stderr ke file bernama '& 1'?
Martín Fixman
120
@ Martin:2>'&1'
632
echo test > afile.txt

mengarahkan ulang stdout ke afile.txt. Ini sama dengan melakukan

echo test 1> afile.txt

Untuk mengarahkan ulang stderr, Anda harus:

echo test 2> afile.txt

>& adalah sintaks untuk mengalihkan aliran ke deskriptor file lain - 0 adalah stdin, 1 adalah stdout, dan 2 adalah stderr.

Anda dapat mengarahkan stdout ke stderr dengan melakukan:

echo test 1>&2 # or echo test >&2

Atau sebaliknya:

echo test 2>&1

Jadi, singkatnya ... 2>mengarahkan ulang stderr ke file (tidak ditentukan), menambahkan &1pengalihan stderr ke stdout.

dbr
sumber
5
Apakah ini masuk akal bagi Anda java ... 2&1 >> data.log,, saya melihat salah satu rekan saya melakukan ini?
Thang Pham
5
@Harry yang terlihat seperti shell yang bukan bash, atau salah ketik .. cmd 2>&1 >> somefile.logakan menambahkan stdout / stderr ke file - pada dasarnya sama seperti di atas, dengan >> filemenambahkan
dbr
73
@ dbr cmd 2>&1 >>filetidak mengarahkan stderr ke file, tetapi cmd >> file 2>&1melakukan. Urutan penting. Dalam kasus pertama, stderr diarahkan ke stdout shell (mungkin tty jika perintah dimasukkan secara interaktif), dan kemudian stdout diarahkan ke file. Dalam kasus kedua, stdout diarahkan ke file, dan kemudian stderr diarahkan ke tempat yang sama.
William Pursell
2
Saya suka jawaban di atas, tetapi bisa menjadi sentuhan yang lebih jelas. "2> & 1" mengarahkan stderr ke target stdout. Jadi jika Anda memiliki sesuatu seperti "ls-l >> direktoriContents 2> & 1" Hasilnya akan menjadi file bernama directoryContents akan memiliki isi direktori kerja yang ditambahkan padanya. Jika ada kesalahan dalam eksekusi: pesan kesalahan juga akan ditambahkan ke file directoryContents, saat terjadi.
Max West
1
Apakah 0(or 1,2)>&0(or 1,2)seperti opsi untuk mengontrol output? Apakah echo test >test.log 2>&1sama echo test 2>&1 >test.log?
Simin Jie
318

Beberapa trik tentang pengalihan

Beberapa sintaksis tertentu tentang hal ini mungkin memiliki perilaku penting. Ada beberapa sampel sedikit tentang pengalihan, STDERR, STDOUT, dan argumen pemesanan .

1 - Menimpa atau menambahkan?

Simbol >berarti pengalihan .

  • >berarti kirim ke sebagai keseluruhan file yang sudah selesai , timpa target jika ada (lihat noclobberfitur bash di # 3 nanti).
  • >>berarti mengirim dan menambahkan akan menargetkan jika ada.

Bagaimanapun, file akan dibuat jika tidak ada.

2 - Baris perintah shell tergantung pesanan !!

Untuk menguji ini, kita memerlukan perintah sederhana yang akan mengirim sesuatu pada kedua output :

$ ls -ld /tmp /tnt
ls: cannot access /tnt: No such file or directory
drwxrwxrwt 118 root root 196608 Jan  7 11:49 /tmp

$ ls -ld /tmp /tnt >/dev/null
ls: cannot access /tnt: No such file or directory

$ ls -ld /tmp /tnt 2>/dev/null
drwxrwxrwt 118 root root 196608 Jan  7 11:49 /tmp

(Mengharapkan Anda tidak memiliki direktori bernama /tnt, tentu saja;). Baiklah, kita memilikinya !!

Jadi, mari kita lihat:

$ ls -ld /tmp /tnt >/dev/null
ls: cannot access /tnt: No such file or directory

$ ls -ld /tmp /tnt >/dev/null 2>&1

$ ls -ld /tmp /tnt 2>&1 >/dev/null
ls: cannot access /tnt: No such file or directory

Baris perintah terakhir kesedihan STDERRke konsol, dan tampaknya bukan perilaku yang diharapkan ... Tapi ...

Jika Anda ingin membuat beberapa pemfilteran posting tentang satu output, yang lain atau keduanya:

$ ls -ld /tmp /tnt | sed 's/^.*$/<-- & --->/'
ls: cannot access /tnt: No such file or directory
<-- drwxrwxrwt 118 root root 196608 Jan  7 12:02 /tmp --->

$ ls -ld /tmp /tnt 2>&1 | sed 's/^.*$/<-- & --->/'
<-- ls: cannot access /tnt: No such file or directory --->
<-- drwxrwxrwt 118 root root 196608 Jan  7 12:02 /tmp --->

$ ls -ld /tmp /tnt >/dev/null | sed 's/^.*$/<-- & --->/'
ls: cannot access /tnt: No such file or directory

$ ls -ld /tmp /tnt >/dev/null 2>&1 | sed 's/^.*$/<-- & --->/'

$ ls -ld /tmp /tnt 2>&1 >/dev/null | sed 's/^.*$/<-- & --->/'
<-- ls: cannot access /tnt: No such file or directory --->

Perhatikan bahwa baris perintah terakhir dalam paragraf ini persis sama dengan paragraf sebelumnya, di mana saya menulis tampaknya bukan perilaku yang diharapkan (jadi, ini bahkan bisa menjadi perilaku yang diharapkan).

Nah, ada sedikit trik tentang pengalihan, untuk melakukan operasi yang berbeda pada kedua output :

$ ( ls -ld /tmp /tnt | sed 's/^/O: /' >&9 ) 9>&2  2>&1  | sed 's/^/E: /'
O: drwxrwxrwt 118 root root 196608 Jan  7 12:13 /tmp
E: ls: cannot access /tnt: No such file or directory

Catatan: &9deskriptor akan terjadi secara spontan karena ) 9>&2.

Tambahan: nota! Dengan versi baru( >4.0) ada fitur baru dan sintaksis yang lebih seksi untuk melakukan hal-hal semacam ini:

$ ls -ld /tmp /tnt 2> >(sed 's/^/E: /') > >(sed 's/^/O: /')
O: drwxrwxrwt 17 root root 28672 Nov  5 23:00 /tmp
E: ls: cannot access /tnt: No such file or directory

Dan akhirnya untuk format output berjenjang:

$ ((ls -ld /tmp /tnt |sed 's/^/O: /' >&9 ) 2>&1 |sed 's/^/E: /') 9>&1| cat -n
     1  O: drwxrwxrwt 118 root root 196608 Jan  7 12:29 /tmp
     2  E: ls: cannot access /tnt: No such file or directory

Tambahan: nota! Sintaks baru yang sama, dalam dua hal:

$ cat -n <(ls -ld /tmp /tnt 2> >(sed 's/^/E: /') > >(sed 's/^/O: /'))
     1  O: drwxrwxrwt 17 root root 28672 Nov  5 23:00 /tmp
     2  E: ls: cannot access /tnt: No such file or directory

Di mana STDOUTpergi melalui filter tertentu, STDERRke yang lain dan akhirnya kedua output digabungkan melalui filter perintah ketiga.

3 - Sepatah kata tentang noclobberopsi dan >|sintaksis

Itu tentang menimpa :

Meskipun set -o noclobbermenginstruksikan bash untuk tidak menimpa file yang ada, >|sintaksnya membiarkan Anda melewati batasan ini:

$ testfile=$(mktemp /tmp/testNoClobberDate-XXXXXX)

$ date > $testfile ; cat $testfile
Mon Jan  7 13:18:15 CET 2013

$ date > $testfile ; cat $testfile
Mon Jan  7 13:18:19 CET 2013

$ date > $testfile ; cat $testfile
Mon Jan  7 13:18:21 CET 2013

File ditimpa setiap kali, nah sekarang:

$ set -o noclobber

$ date > $testfile ; cat $testfile
bash: /tmp/testNoClobberDate-WW1xi9: cannot overwrite existing file
Mon Jan  7 13:18:21 CET 2013

$ date > $testfile ; cat $testfile
bash: /tmp/testNoClobberDate-WW1xi9: cannot overwrite existing file
Mon Jan  7 13:18:21 CET 2013

Lewati dengan >|:

$ date >| $testfile ; cat $testfile
Mon Jan  7 13:18:58 CET 2013

$ date >| $testfile ; cat $testfile
Mon Jan  7 13:19:01 CET 2013

Membatalkan pilihan ini dan / atau bertanya apakah sudah disetel.

$ set -o | grep noclobber
noclobber           on

$ set +o noclobber

$ set -o | grep noclobber
noclobber           off

$ date > $testfile ; cat $testfile
Mon Jan  7 13:24:27 CET 2013

$ rm $testfile

4 - Trik terakhir dan banyak lagi ...

Untuk mengarahkan ulang kedua output dari perintah yang diberikan, kita melihat bahwa sintaks yang tepat adalah:

$ ls -ld /tmp /tnt >/dev/null 2>&1

untuk kasus khusus ini, ada sintaks pintasan: &>... atau>&

$ ls -ld /tmp /tnt &>/dev/null

$ ls -ld /tmp /tnt >&/dev/null

Nota: jika 2>&1ada, 1>&2adalah sintaks yang benar juga:

$ ls -ld /tmp /tnt 2>/dev/null 1>&2

4b- Sekarang, saya akan membiarkan Anda berpikir tentang:

$ ls -ld /tmp /tnt 2>&1 1>&2  | sed -e s/^/++/
++/bin/ls: cannot access /tnt: No such file or directory
++drwxrwxrwt 193 root root 196608 Feb  9 11:08 /tmp/

$ ls -ld /tmp /tnt 1>&2 2>&1  | sed -e s/^/++/
/bin/ls: cannot access /tnt: No such file or directory
drwxrwxrwt 193 root root 196608 Feb  9 11:08 /tmp/

4c- Jika Anda tertarik pada informasi lebih lanjut

Anda dapat membaca manual yang bagus dengan menekan:

man -Len -Pless\ +/^REDIRECTION bash

di sebuah konsol ;-)

F. Hauri
sumber
5
Bacaan lebih lanjut: Jika Anda suka ini, Anda dapat menghargai: Bagaimana penyalahgunaan pengalihan dapat memberikan perilaku aneh
F. Hauri
1
Bacaan lebih lanjut || : Suatu fungsi untuk menyimpan kedua output ke dalam variabel
F. Hauri
130

Saya menemukan pos brilian tentang pengalihan: Semua tentang pengalihan

Mengarahkan output standar dan kesalahan standar ke file

$ command &> file

One-liner ini menggunakan &>operator untuk mengalihkan aliran output - stdout dan stderr - dari perintah ke file. Ini adalah jalan pintas Bash untuk dengan cepat mengarahkan ulang kedua aliran ke tujuan yang sama.

Berikut adalah tampilan tabel deskriptor file setelah Bash mengalihkan kedua stream:

Masukkan deskripsi gambar di sini

Seperti yang Anda lihat, stdout dan stderr sekarang menunjuk ke file. Jadi apa pun yang ditulis untuk stdout dan stderr akan ditulis file.

Ada beberapa cara untuk mengarahkan kedua aliran ke tujuan yang sama. Anda dapat mengarahkan setiap aliran satu demi satu:

$ command> file 2> & 1

Ini adalah cara yang jauh lebih umum untuk mengarahkan kedua aliran ke file. Stdout pertama diarahkan ke file, dan kemudian stderr diduplikasi sama dengan stdout. Jadi kedua aliran akhirnya menunjuk ke file.

Ketika Bash melihat beberapa pengalihan, ia memprosesnya dari kiri ke kanan. Mari kita melalui langkah-langkah dan melihat bagaimana itu terjadi. Sebelum menjalankan perintah apa pun, tabel deskriptor file Bash terlihat seperti ini:

Masukkan deskripsi gambar di sini

Sekarang Bash memproses pengalihan> file pertama. Kami telah melihat ini sebelumnya dan itu membuat stdout menunjuk ke file:

Masukkan deskripsi gambar di sini

Bash Selanjutnya melihat pengalihan kedua 2> & 1. Kami belum pernah melihat pengalihan ini sebelumnya. Ini duplikat file deskriptor 2 menjadi salinan file deskriptor 1 dan kami mendapatkan:

Masukkan deskripsi gambar di sini

Kedua aliran telah dialihkan ke file.

Namun hati-hati di sini! Penulisan

perintah> file 2> & 1

tidak sama dengan menulis:

$ command 2> & 1> file

Urutan pengalihan penting di Bash! Perintah ini hanya mengarahkan keluaran standar ke file. Stderr masih akan mencetak ke terminal. Untuk memahami mengapa itu terjadi, mari kita kembali ke langkah-langkahnya. Jadi sebelum menjalankan perintah, tabel deskriptor file terlihat seperti ini:

Masukkan deskripsi gambar di sini

Sekarang Bash memproses pengalihan dari kiri ke kanan. Pertama melihat 2 & 1 sehingga duplikat stderr ke stdout. Tabel deskriptor file menjadi:

Masukkan deskripsi gambar di sini

Sekarang Bash melihat pengalihan kedua >file,, dan pengalihan stdout ke file:

Masukkan deskripsi gambar di sini

Apakah Anda melihat apa yang terjadi di sini? Stdout sekarang menunjuk ke file, tetapi stderr masih menunjuk ke terminal! Semua yang ditulis ke stderr masih dicetak ke layar! Jadi berhati-hatilah dengan urutan pengalihan!

Perhatikan juga bahwa dalam Bash, menulis

$ command &> file

persis sama dengan:

$ command> & file

Deen John
sumber
3
Dua yang terakhir berbeda jika "perintah" berakhir dengan angka, seperti yang kemudian diambil sebagai deskriptor file opsional untuk>&
MM
Gambar dan penjelasannya sangat bagus! Bisakah Anda menguraikan arti "duplikat" yang sebenarnya? Anda menyebutkan, "Yang ini [2> & 1] menggandakan deskriptor file 2 menjadi salinan deskriptor file 1". Kedengarannya seperti stderr diduplikasi ke stdout. Tetapi jika itu masalahnya, haruskah saya juga melihat kesalahan /dev/tty0?
HCSF
87

Angka-angka mengacu pada deskriptor file (fd).

  • Nol adalah stdin
  • Satu adalah stdout
  • Dua adalah stderr

2>&1 arahan ulang fd 2 ke 1.

Ini berfungsi untuk sejumlah deskriptor file jika program menggunakannya.

Anda dapat melihat /usr/include/unistd.hjika Anda melupakannya:

/* Standard file descriptors.  */
#define STDIN_FILENO    0   /* Standard input.  */
#define STDOUT_FILENO   1   /* Standard output.  */
#define STDERR_FILENO   2   /* Standard error output.  */

Yang mengatakan saya telah menulis alat C yang menggunakan deskriptor file non-standar untuk log kustom sehingga Anda tidak melihatnya kecuali Anda mengarahkannya ke file atau sesuatu.

Colin Burnett
sumber
58

Konstruk itu mengirimkan aliran kesalahan standar ( stderr) ke lokasi saat ini dari keluaran standar (stdout ) - masalah mata uang ini tampaknya telah diabaikan oleh jawaban lain.

Anda dapat mengalihkan penanganan keluaran ke yang lain dengan menggunakan metode ini, tetapi ini paling sering digunakan untuk menyalurkan stdoutdanstderr stream ke satu aliran untuk diproses.

Beberapa contoh adalah:

# Look for ERROR string in both stdout and stderr.
foo 2>&1 | grep ERROR

# Run the less pager without stderr screwing up the output.
foo 2>&1 | less

# Send stdout/err to file (with append) and terminal.
foo 2>&1 |tee /dev/tty >>outfile

# Send stderr to normal location and stdout to file.
foo >outfile1 2>&1 >outfile2

Perhatikan bahwa yang terakhir tidak akan mengarahkan stderrke outfile2- itu mengarahkan kembali ke apa stdoutketika argumen itu ditemui ( outfile1) dan kemudian dialihkan stdoutke outfile2.

Ini memungkinkan beberapa tipuan yang cukup canggih.

paxdiablo
sumber
5
Meskipun bahwa contoh terakhir akan lebih jelas sebagai: foo> outfile2 2> outfile1
Michael Cramer
3
Lebih jelas, ya, tapi itu tidak akan menunjukkan sifat "posisi" redirection. Contoh dibuat karena biasanya tidak berguna untuk melakukan ini dalam satu baris - metode ini menjadi sangat berguna ketika pihak yang berbeda bertanggung jawab atas bagian yang berbeda dari pengalihan. Misalnya, ketika skrip melakukan satu pengalihan sedikit dan Anda menjalankannya dengan sedikit lainnya.
paxdiablo
5
Aku baru sadar bahwa contoh terakhir juga menyelesaikan kebingungan berdiri lama saya mengenai mengapa hal ini: some_program 2>&1 > /dev/nulltidak bekerja seperti ini: some_program > /dev/null 2>&1.
snapfractalpop
Komentar Anda tentang contoh terakhir bernilai surat-surat emas :-) Saya tidak pernah berpikir bahwa argumen pengalihan ini adalah posisi ... Saya pikir ini cukup penting untuk diketahui.
Nils-o-mat
20

2>&1adalah konstruksi shell POSIX. Berikut ini rincian, token dengan token:


2: Deskriptor file output " Standard error ".

>&: Gandakan operator Penjelasan File Keluaran (varian dari operator Pengalihan Keluaran> ). Diberikan [x]>&[y], deskriptor file yang dilambangkan dengan xdibuat menjadi salinan deskriptor file output y.

1" Standar keluaran " file output descriptor.

Ekspresi 2>&1menyalin deskriptor file 1ke lokasi 2, sehingga output apa pun ditulis ke 2("kesalahan standar") di lingkungan eksekusi pergi ke file yang sama yang awalnya dijelaskan oleh 1("output standar").


Penjelasan lebih lanjut:

File Descriptor : "Integer unik non-negatif per proses yang digunakan untuk mengidentifikasi file terbuka untuk tujuan akses file."

Output / kesalahan standar : Lihat catatan berikut di bagian Redirection dari dokumentasi shell:

File yang terbuka diwakili oleh angka desimal dimulai dengan nol. Nilai terbesar yang mungkin ditentukan oleh implementasi; namun, semua implementasi harus mendukung setidaknya 0 hingga 9, inklusif, untuk digunakan oleh aplikasi. Angka-angka ini disebut "file deskriptor". Nilai 0, 1, dan 2 memiliki makna khusus dan penggunaan konvensional dan tersirat oleh operasi pengalihan tertentu; mereka disebut sebagai input standar, output standar, dan kesalahan standar, masing-masing. Program biasanya mengambil input dari input standar, dan menulis output pada output standar. Pesan kesalahan biasanya ditulis pada kesalahan standar. Operator pengalihan dapat didahului oleh satu digit atau lebih (tanpa karakter yang diintervensi) untuk menunjuk nomor deskriptor file.

wjordan
sumber
19

2 adalah kesalahan standar konsol.

1 adalah output standar konsol.

Ini adalah Unix standar, dan Windows juga mengikuti POSIX.

Misal saat Anda berlari

perl test.pl 2>&1

kesalahan standar dialihkan ke output standar, sehingga Anda dapat melihat kedua output secara bersamaan:

perl test.pl > debug.log 2>&1

Setelah eksekusi, Anda dapat melihat semua output, termasuk kesalahan, di debug.log.

perl test.pl 1>out.log 2>err.log

Kemudian output standar pergi ke out.log, dan standar error ke err.log.

Saya sarankan Anda untuk mencoba memahami ini.

Marcus Thornton
sumber
Sampel kedua salah: karena urutan prioritas STDERR dialihkan ke STDOUT , hanya STDOUT default yang akan ditulis ke debug.log (bukan STDERR ) lihat jawaban saya (paragraf # 2)! Untuk memastikan keduanya diarahkan ke file yang sama, Anda harus membalikkan arahan arahan ulang:perl test.pl > debug.log 2>&1
F. Hauri
16

Untuk menjawab pertanyaan Anda: Dibutuhkan output kesalahan (biasanya dikirim ke stderr) dan tulis ke output standar (stdout).

Ini sangat membantu dengan, misalnya 'lebih' ketika Anda membutuhkan halaman untuk semua output. Beberapa program seperti mencetak informasi penggunaan ke dalam stderr.

Untuk membantumu mengingat

  • 1 = output standar (di mana program mencetak output normal)
  • 2 = kesalahan standar (di mana program mencetak kesalahan)

"2> & 1" hanya menunjukkan semua yang dikirim ke stderr, sebagai ganti stdout.

Saya juga merekomendasikan membaca posting ini tentang kesalahan redirect di mana subjek ini dibahas secara detail lengkap.

Andrioid
sumber
11

Dari sudut pandang seorang programmer, ini berarti persis seperti ini:

dup2(1, 2);

Lihat halaman manual .

Memahami itu 2>&1adalah salinan juga menjelaskan mengapa ...

command >file 2>&1

... tidak sama dengan ...

command 2>&1 >file

Yang pertama akan mengirim kedua aliran ke file, sedangkan yang kedua akan mengirim kesalahan stdout, dan output biasa ke file.

am
sumber
9

Saya menemukan ini sangat membantu jika Anda seorang pemula membaca ini

Pembaruan:
Di Linux atau Sistem Unix ada dua tempat program mengirim output ke: Output standar (stdout) dan Kesalahan Standar (stderr) . Anda dapat mengarahkan output ini ke file apa pun.

Seperti jika Anda melakukan ini, tidak

ls -a > output.txt

ada yang akan dicetak di konsol semua output (stdout) diarahkan ke file output.

Dan jika Anda mencoba mencetak konten file apa pun yang tidak keluar berarti output akan menjadi kesalahan seperti jika Anda mencetak test.txt yang tidak ada dalam direktori saat ini.

cat test.txt > error.txt

Output akan menjadi

cat: test.txt :No such file or directory

Tetapi file error.txt akan kosong karena kami mengarahkan stdout ke file bukan stderr.

jadi kita memerlukan deskriptor file (deskriptor file tidak lebih dari bilangan bulat positif yang mewakili file terbuka. Anda dapat mengatakan deskriptor adalah id file unik) untuk memberi tahu shell jenis output yang kita kirim ke file. Di sistem Unix / Linux 1 untuk stdout dan 2 untuk stderr .

jadi sekarang jika Anda melakukan ini

ls -a 1> output.txtberarti Anda mengirim output standar (stdout) ke output.txt.

dan jika Anda melakukan ini

cat test.txt 2> error.txtberarti Anda mengirim Standard Error (stderr) ke error.txt.

&1digunakan untuk referensi nilai deskriptor file 1 (stdout). Sekarang kamu bisa melakukan ini

Sekarang ke titik 2>&1berarti "Redirect stderr ke tempat yang sama kita mengarahkan stdout"


cat maybefile.txt > output.txt 2>&1

Output standar (stdout) dan Kesalahan Standar (stderr) akan dialihkan ke output.txt.

Terima kasih kepada Ondrej K. yang telah menunjukkan

Küñdàñ Börà
sumber
1
Hanya tautan yang bermasalah. Tautan dapat menjadi tidak berfungsi karena membuat jawaban tidak berguna. Anda harus selalu memasukkan cukup detail dalam jawaban itu sendiri.
Ondrej K.
7

Orang, selalu ingat paxdiablo petunjuk 's tentang saat lokasi target pengalihan ... Ini adalah penting.

Mnemonik pribadi saya untuk 2>&1operator adalah ini:

  • Pikirkan &sebagai makna 'and'atau'add' (karakternya adalah sebuah amper - dan , bukan?)
  • Jadi itu menjadi: 'redirect 2(stderr) ke tempat1 (stdout) sudah / saat ini dan tambahkan kedua aliran' .

Karya-karya mnemonic yang sama untuk pengalihan lainnya yang sering digunakan juga, 1>&2:

  • Pikirkan & makna andatau add... (Anda mendapatkan ide tentang ampersand, ya?)
  • Jadi itu menjadi: 'redirect 1(stdout) ke tempat 2(stderr) sudah / saat ini dan tambahkan kedua aliran' .

Dan selalu ingat: Anda harus membaca rantai pengalihan 'dari akhir', dari kanan ke kiri ( bukan dari kiri ke kanan).

Kurt Pfeifle
sumber
7

Mengarahkan Input

Pengalihan input menyebabkan file yang namanya dihasilkan dari perluasan kata yang akan dibuka untuk dibaca pada deskriptor file n, atau input standar (deskriptor file 0) jika n tidak ditentukan.

Format umum untuk mengarahkan ulang input adalah:

[n]<word

Mengarahkan Output

Redirection of output menyebabkan file yang namanya dihasilkan dari perluasan kata yang akan dibuka untuk menulis pada deskriptor file n, atau output standar (file descriptor 1) jika n tidak ditentukan. Jika file tidak ada itu dibuat; jika memang ada itu dipotong ke ukuran nol.

Format umum untuk mengarahkan ulang output adalah:

[n]>word

Memindahkan Penjelas File

Operator pengalihan,

[n]<&digit-

memindahkan digit deskriptor file ke deskriptor file n, atau input standar (file deskriptor 0) jika n tidak ditentukan. digit ditutup setelah digandakan ke n.

Demikian pula dengan operator redirection

[n]>&digit-

memindahkan digit deskriptor file ke deskriptor file n, atau output standar (file deskriptor 1) jika n tidak ditentukan.

Ref:

man bash

Ketik /^REDIRECTuntuk mencari ke redirectionbagian tersebut, dan pelajari lebih lanjut ...

Versi online ada di sini: 3.6 Pengalihan

PS:

Banyak waktu, manadalah alat yang ampuh untuk belajar Linux.

yurenchen
sumber
6

Asalkan /footidak ada di sistem Anda dan /tmptidak ...

$ ls -l /tmp /foo

akan mencetak konten /tmpdan mencetak pesan kesalahan untuk/foo

$ ls -l /tmp /foo > /dev/null

akan mengirim konten /tmpke /dev/nulldan mencetak pesan kesalahan untuk/foo

$ ls -l /tmp /foo 1> /dev/null

akan melakukan hal yang persis sama (perhatikan 1 )

$ ls -l /tmp /foo 2> /dev/null

akan mencetak konten /tmpdan mengirim pesan kesalahan ke/dev/null

$ ls -l /tmp /foo 1> /dev/null 2> /dev/null

akan mengirim daftar dan pesan kesalahan ke /dev/null

$ ls -l /tmp /foo > /dev/null 2> &1

adalah singkatan

Matijs
sumber
5

Ini seperti melewatkan kesalahan ke stdout atau terminal.

Artinya, cmdbukan perintah:

$cmd 2>filename
cat filename

command not found

Kesalahan dikirim ke file seperti ini:

2>&1

Kesalahan standar dikirim ke terminal.

Kalanidhi
sumber
1

0 untuk input, 1 untuk stdout dan 2 untuk stderr.

One Tip : somecmd >1.txt 2>&1benar, sementara somecmd 2>&1 >1.txtbenar-benar salah tanpa efek!

ch271828n
sumber
1

unix_commands 2>&1

Ini digunakan untuk mencetak kesalahan ke terminal.

Berikut ini menggambarkan prosesnya

  • Ketika kesalahan dihasilkan, mereka ditulis ke dalam &2"buffer" alamat memori kesalahan standar , dari mana 2referensi aliran kesalahan standar .
  • Ketika output diproduksi, itu ditulis ke dalam &1"buffer" alamat memori output output standar , dari mana 1referensi aliran output standar .

Jadi ambil unix_commandsaliran kesalahan standar 2, dan redirect >aliran (kesalahan) ke alamat memori keluaran standar &1, sehingga aliran tersebut akan dialirkan ke terminal dan dicetak.

Timbul
sumber