GNU/Linux >> Belajar Linux >  >> Linux

Apakah>&- Lebih Efisien Daripada>/dev/null?

Kemarin saya membaca komentar SO ini yang mengatakan bahwa di shell (setidaknya bash ) >&- “memiliki hasil yang sama dengan” >/dev/null .

Komentar itu sebenarnya mengacu pada panduan ABS sebagai sumber informasinya. Tapi sumber itu mengatakan bahwa >&- sintaks "menutup deskriptor file".

Tidak jelas bagi saya apakah dua tindakan menutup deskriptor file dan mengarahkannya ke perangkat nol benar-benar setara. Jadi pertanyaan saya adalah:benarkah?

Di permukaan tampaknya menutup deskriptor seperti menutup pintu tetapi mengarahkannya ke perangkat nol membuka pintu ke limbo! Keduanya tidak tampak persis sama bagi saya karena jika saya melihat pintu yang tertutup, saya tidak akan mencoba membuang apa pun darinya, tetapi jika saya melihat pintu yang terbuka, saya akan berasumsi bahwa saya bisa.

Dengan kata lain, saya selalu bertanya-tanya apakah >/dev/null artinya cat mybigfile >/dev/null sebenarnya akan memproses setiap byte file dan menulisnya ke /dev/null yang melupakannya. Di sisi lain, jika shell menemukan deskriptor file tertutup, saya cenderung berpikir (tetapi saya tidak yakin) bahwa shell tidak akan menulis apa pun, meskipun pertanyaannya tetap apakah cat akan tetap membaca setiap byte.

Komentar ini mengatakan >&- dan >/dev/nullharus ” sama saja, tapi itu bukan jawaban yang begitu menggema bagi saya. Saya ingin memiliki jawaban yang lebih otoritatif dengan beberapa referensi ke standar atau inti sumber atau tidak…

Jawaban yang Diterima:

Tidak, Anda pasti tidak ingin menutup deskriptor file 0, 1 dan 2.

Jika Anda melakukannya, pertama kali aplikasi membuka file, itu akan menjadi stdin/stdout/stderr…

Misalnya, jika Anda melakukannya:

echo text | tee file >&-

Ketika tee (setidaknya beberapa implementasi, seperti busybox') membuka file untuk menulis, itu akan terbuka pada deskriptor file 1 (stdout). Jadi tee akan menulis text dua kali ke dalam file :

$ echo text | strace tee file >&-
[...]
open("file", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 1
read(0, "textn", 8193)                 = 5
write(1, "textn", 5)                   = 5
write(1, "textn", 5)                   = 5
read(0, "", 8193)                       = 0
exit_group(0)                           = ?

Itu telah diketahui menyebabkan kerentanan keamanan. Misalnya:

chsh 2>&-

Dan chsh (aplikasi setuid) mungkin berakhir dengan menulis pesan kesalahan di /etc/passwd .

Beberapa alat dan bahkan beberapa perpustakaan mencoba mencegahnya. Misalnya GNU tee akan memindahkan deskriptor file ke satu di atas 2 jika file yang dibuka untuk penulisan diberi 0, 1, 2 saat busybox tee tidak akan.

Terkait:Linux – Apa file default untuk `hostname`?

Sebagian besar alat, jika mereka tidak dapat menulis ke stdout (karena misalnya tidak terbuka), akan melaporkan pesan kesalahan pada stderr (dalam bahasa pengguna yang berarti pemrosesan ekstra untuk membuka dan mengurai file lokalisasi...), jadi itu akan secara signifikan kurang efisien, dan mungkin menyebabkan program gagal.

Bagaimanapun, itu tidak akan lebih efisien. Program masih akan melakukan write() panggilan sistem. Itu hanya bisa lebih efisien jika program berhenti menulis ke stdout/stderr setelah write() pertama gagal panggilan sistem, tetapi program umumnya tidak melakukan itu. Mereka biasanya keluar dengan kesalahan atau terus mencoba.


Linux
  1. Apa itu file /dev/zero dan /dev/null di Linux?

  2. Cara menjalankan file sh dari file sh lain

  3. DD dari /dev/zero ke /dev/null...apa yang sebenarnya terjadi

  1. Seberapa Portabel /dev/stdin, /dev/stdout Dan /dev/stderr?

  2. gema atau cetak /dev/stdin /dev/stdout /dev/stderr

  3. Buat perangkat blok virtual yang menulis ke /dev/null

  1. Kapan Menggunakan /dev/random Vs /dev/urandom?

  2. Bagaimana Membungkam Sepenuhnya Cronjob Ke /dev/null/?

  3. Bagaimana cara menyandikan base64 /dev/random atau /dev/urandom?