Kadang-kadang saya perlu menentukan "jalan-setara" dari salah satu IO standar stream ( stdin
, stdout
, stderr
). Karena 99% dari waktu saya bekerja dengan Linux, saya hanya perlu /dev/
untuk mendapatkan /dev/stdin
, dll, dan ini " sepertinya melakukan hal yang benar". Tetapi, untuk satu hal, saya selalu merasa tidak nyaman dengan alasan yang demikian (karena, tentu saja, "tampaknya berhasil" sampai tidak berhasil). Selain itu, saya tidak memiliki akal yang baik untuk seberapa portabel manuver ini.
Jadi saya punya beberapa pertanyaan:
Dalam konteks Linux, apakah aman (ya / tidak) untuk menyamakan
stdin
,stdout
danstderr
dengan/dev/stdin
,/dev/stdout
, dan/dev/stderr
?Secara umum, apakah kesetaraan ini "cukup portabel "?
Saya tidak dapat menemukan referensi POSIX.
Jawaban:
Sudah tersedia di Linux kembali ke masa prasejarahnya. Ini bukan POSIX, meskipun banyak shell aktual (termasuk AT&T
ksh
danbash
) akan mensimulasikannya jika tidak ada di OS; perhatikan bahwa simulasi ini hanya berfungsi pada level shell (yaitu redirection atau parameter baris perintah, bukan sebagai argumen eksplisit untuk egopen()
). Yang mengatakan, itu harus tersedia pada sebagian besar sistem Unix komersial, satu atau lain cara (kadang-kadang dieja/dev/fd/N
untuk berbagai bilangan bulatN
, tetapi sebagian besar sistem dengan itu akan memberikan symlink seperti Linux dan * BSD lakukan).sumber
/dev/std{in,out,err}
secara khusus terdaftar sebagai bukan bagian dari standar POSIX.1-2008 .ash
tidak mendukung/dev/stdout
initrd ( git.razvi.ro/… )yang
/dev/std{in,out,err}
file biasanya hanya symlink ke/proc/self/fd/{0,1,2}
(masing-masing). Karena itu tidak ada yang diperoleh dari menggunakan metode yang didefinisikan POSIX.Jika Anda ingin mematuhi POSIX, cara terbaik untuk melakukannya adalah dengan menggunakan pengalihan output. Redirection output shell didefinisikan dalam standar POSIX . Selain itu nomor deskriptor file STDIN, STDOUT, STDERR juga merupakan bagian dari POSIX .
Singkatnya, hal-hal seperti
>&2
dijamin bekerja.Satu hal penting yang perlu diperhatikan adalah penggunaan STDIN, STDOUT, dan STDERR bersifat subyektif terhadap bagaimana program dimulai. Jika program dimulai dengan deskriptor file 1 sebagai pegangan terbuka untuk file, maka program Anda hanya harus menerimanya. Bahkan jika Anda memiliki program terbuka
/dev/stdout
, semua itu akan lakukan adalah membuka file deskriptor 1 yang masih akan mengarah ke file itu.Jika ini yang ingin Anda lakukan, Anda perlu membuka TTY secara langsung. Biasanya, tanpa ada pengalihan, STDIN, STDOUT, dan STDERR semuanya hanya buka deskriptor file yang menunjuk ke TTY yang sama. Sama sekali tidak ada yang lebih dari itu.
sumber
/proc/self/fd/1
atau/dev/fd/1
merupakan bagian dari POSIX?/dev/std???
hanya symlinks/proc/self/fd
di Linux.POSIX 7 mengatakan itu adalah ekstensi.
Definisi Dasar , Bagian 2.1.1 Persyaratan:
Ditemukan dengan memahami POSIX HTML: Di mana daftar fungsi POSIX C API?
Juga cukup aneh,
uuencode
alat ini memberikan/dev/stdout
efek ajaib :Dokumentasi kernel Linux mengatakan semua sistem harus memilikinya.
https://github.com/torvalds/linux/blob/master/Documentation/admin-guide/devices.rst
Namun, saya tidak dapat menemukan di mana symlink tersebut dibuat di kernel (distro disediakan?).
sumber
/ dev / {stdout, stdin, stderr} berfungsi di Bash pada platform ini:
Tetapi gagal dalam csh pada ini:
sumber
bash
istimewa karena dapat dikompilasi untuk ditangani/dev/fd/x
sendiri untuk pengalihan pada sistem yang tidak memiliki/dev/fd
Satu masalah dengan
/dev/stdout
dan teman adalah bahwa Anda mungkin tidak memiliki izin untuk menulis kepada mereka dalam keadaan tertentu. Sebagai contoh, saya pernah menjumpai ini ketika memohon skrip dari Nix , dan saya membayangkan alat serupa yang menjalankan skrip di penjara / kotak pasir / wadah / VMs / dll. mungkin mengalami masalah serupa.Menggunakan sintaks seperti
1>&2
bekerja dalam kasus ini dan, karena saya tahu saya akan berjalan di Bash, saya bisa menggunakan proses substitusi untuk perintah yang mengharapkan nama file.sumber