Apa yang dilakukan “3> & 1 1> & 2 2> & 3” dalam sebuah skrip?

69

Saya melihat baris ini dalam sebuah skrip:

DEVICE=`dialog --inputbox "Festplatten-Laufzeit auslesen. Gebe Sie das 
gewünschte Device an: " 0 70 "" 3>&1 1>&2 2>&3`

apa yang

3>&1 1>&2 2>&3

perbuatan? Saya tahu bahwa 1 = stdout dan 2 = stderr, tetapi untuk apa 3dan &untuk apa?

Jsterr
sumber
3
Lihat juga File deskriptor & skrip shell dan Kapan Anda akan menggunakan deskriptor file tambahan?
Gilles 'SO- berhenti bersikap jahat'

Jawaban:

77

Angka-angka adalah deskriptor file dan hanya tiga yang pertama (dimulai dengan nol) yang memiliki makna standar:

0 - stdin
1 - stdout
2 - stderr

Jadi masing-masing angka ini dalam perintah Anda merujuk ke deskriptor file. Anda bisa mengarahkan file descriptor ke file dengan >atau mengarahkannya ke deskriptor file lain dengan>&

Di 3>&1dalam baris perintah Anda akan membuat deskriptor file baru dan mengarahkan ulang ke 1yang ada STDOUT. Sekarang 1>&2akan mengarahkan file deskriptor 1 ke STDERRdan 2>&3akan mengarahkan file deskriptor 2 ke 3 STDOUT.

Jadi pada dasarnya Anda beralih STDOUTdan STDERR, ini adalah langkah-langkahnya:

  1. Buat fd 3 baru dan arahkan ke fd 1
  2. Redirect file deskriptor 1 ke file deskriptor 2. Jika kita tidak menyimpan file deskriptor dalam 3, kita akan kehilangan target.
  3. Redirect file deskriptor 2 ke file deskriptor 3. Sekarang file deskriptor satu dan dua dialihkan.

Sekarang jika program mencetak sesuatu ke deskriptor file 1, itu akan dicetak ke deskriptor file 2 dan sebaliknya.

Ulrich Dangel
sumber
Anda telah mengatakan "3> & 1 pada baris perintah Anda akan membuat deskriptor file baru dan mengarahkannya ke 1 yang STDOUT". Tapi bukankah 1 berarti STDIN?
sofs1
19

Bertukar stdoutdan stderr.

>nameberarti mengarahkan output ke file name.

>&numberberarti redirect output ke file descriptor number.

Jadi &diperlukan untuk memberitahu shell maksud Anda deskriptor file, bukan nama file.

Deskriptor file adalah angka yang merujuk ke file yang sudah terbuka. Yang standar adalah 0untuk input standar, 1untuk output standar atau 2untuk kesalahan standar. Anda juga dapat menggunakan nomor lain, yang akan membuat deskriptor file baru, seperti saat Anda membuat variabel baru dengan var=value.

Secara default, kedua file descriptor 1dan 2pergi ke /dev/tty, jadi jika Anda menjalankan somecommand 3>&1 1>&2 2>&3shell baru, itu tidak mengubah apa pun (kecuali sekarang Anda memiliki file deskriptor nomor 3).

Tetapi jika suatu tempat sebelumnya dalam skrip melakukan pengalihan menggunakan exec (misalnya exec 2>error.log), atau skrip dijalankan dengan baris perintah termasuk pengalihan (mis. ./thescript 2>error.log), Maka swapping stdout dan stderr akan melakukan sesuatu.

Dalam kasus spesifik Anda, perintah yang mengganti stdout dan stderr adalah dialog. Melihat halaman manualnya , saya mengerti

Some widgets, e.g., checklist, will write text to dialog's output.
Normally that is the standard error

jadi mungkin orang yang menulis skrip itu ingin dialogkeluaran stdoutbukan stderrkarena alasan tertentu.

Lihat juga Urutan pengalihan

Mikel
sumber
1

Penulis skrip mendefinisikan fd 3 seperti:

exec 3<> File.txt

Buka "File.txt" dan tetapkan fd 3 untuk itu. Deskriptor file maksimum: 255

read -n 4 <&3

Baca hanya 4 karakter.

echo -n . >&3

Tulis titik desimal di sana.

exec 3>&-

Tutup fd 3.

cat File.txt

==> 1234.67890

Jonathan Jackson
sumber