Di
./binary < file
binary
stdin adalah file yang dibuka dalam mode read-only. Catatan yang bash
tidak membaca file sama sekali, itu hanya membukanya untuk membaca file descriptor 0 (stdin) dari proses yang dijalankannya binary
.
Di:
./binary << EOF
test
EOF
Bergantung pada shell, binary
stdin akan berupa file sementara yang dihapus (AT&T ksh, zsh, bash ...) yang berisi test\n
seperti yang diletakkan di sana oleh shell atau ujung pembacaan pipa ( dash
, yash
; dan shell menulis test\n
secara paralel) di ujung lain pipa). Dalam kasus Anda, jika Anda menggunakan bash
, itu akan menjadi file temp.
Di:
cat file | ./binary
Tergantung pada cangkang, binary
stdin akan menjadi ujung pembacaan pipa, atau salah satu ujung pasangan soket di mana arah penulisan telah ditutup (ksh93) dan cat
sedang menulis konten file
di ujung lainnya.
Ketika stdin adalah file biasa (sementara atau tidak), itu dapat dicari. binary
dapat pergi ke awal atau akhir, mundur, dll. Ini juga dapat mmap itu, melakukan beberapa ioctl()s
seperti FIEMAP / FIBMAP (jika menggunakan <>
bukan <
, itu bisa memotong / membuat lubang di dalamnya, dll).
pasangan pipa dan soket di sisi lain adalah sarana komunikasi antar-proses, tidak banyak yang binary
bisa dilakukan selain read
data (meskipun ada juga beberapa operasi seperti beberapa pipa-spesifik ioctl()
yang bisa dilakukan pada mereka dan tidak pada file biasa) .
Sebagian besar waktu, itu kemampuan yang hilang untuk seek
yang menyebabkan aplikasi gagal / mengeluh ketika bekerja dengan pipa, tetapi bisa menjadi salah satu panggilan sistem lain yang berlaku pada file biasa namun tidak pada berbagai jenis file (seperti mmap()
, ftruncate()
, fallocate()
) . Di Linux, ada juga perbedaan besar dalam perilaku ketika Anda membuka /dev/stdin
ketika fd 0 berada di atas pipa atau pada file biasa.
Ada banyak perintah di luar sana yang hanya dapat menangani file yang dapat dicari , tetapi ketika itu masalahnya, itu umumnya tidak untuk file yang terbuka di stdin mereka.
$ unzip -l file.zip
Archive: file.zip
Length Date Time Name
--------- ---------- ----- ----
11 2016-12-21 14:43 file
--------- -------
11 1 file
$ unzip -l <(cat file.zip)
# more or less the same as cat file.zip | unzip -l /dev/stdin
Archive: /proc/self/fd/11
End-of-central-directory signature not found. Either this file is not
a zipfile, or it constitutes one disk of a multi-part archive. In the
latter case the central directory and zipfile comment will be found on
the last disk(s) of this archive.
unzip: cannot find zipfile directory in one of /proc/self/fd/11 or
/proc/self/fd/11.zip, and cannot find /proc/self/fd/11.ZIP, period.
unzip
perlu membaca indeks yang disimpan di akhir file, dan kemudian mencari dalam file untuk membaca anggota arsip. Tapi di sini, file (reguler dalam kasus pertama, pipa dalam yang kedua) diberikan sebagai argumen path unzip
, dan unzip
membukanya sendiri (biasanya pada fd selain 0) alih-alih mewarisi fd yang sudah dibuka oleh induknya. Itu tidak membaca file zip dari stdin-nya. stdin banyak digunakan untuk interaksi pengguna.
Jika Anda menjalankan itu binary
dari Anda tanpa pengalihan pada prompt shell interaktif yang berjalan di emulator terminal, maka binary
stdin akan diwarisi dari induknya shell, yang dengan sendirinya akan mewarisinya dari induknya terminal emulator dan akan menjadi Perangkat pty terbuka dalam mode baca + tulis (sesuatu seperti /dev/pts/n
).
Perangkat-perangkat itu juga tidak bisa dicari. Jadi, jika binary
berfungsi dengan baik ketika mengambil input dari terminal, mungkin masalahnya bukan tentang mencari.
Jika 14 itu dimaksudkan sebagai errno (kode kesalahan yang ditetapkan oleh kegagalan panggilan sistem), maka pada sebagian besar sistem, itu akan menjadi EFAULT
( Alamat buruk ). The read()
system call akan gagal dengan kesalahan bahwa jika diminta untuk membaca ke alamat memori yang tidak dapat ditulis. Itu akan terlepas dari apakah fd membaca data dari titik ke pipa atau file biasa dan umumnya akan menunjukkan bug 1 .
binary
mungkin menentukan jenis file yang terbuka pada stdin (with fstat()
) dan mengalami bug ketika itu bukan file biasa atau perangkat tty.
Sulit dikatakan tanpa mengetahui lebih lanjut tentang aplikasi tersebut. Menjalankannya di bawah strace
(atau truss
/ tusc
setara pada sistem Anda) dapat membantu kami melihat apa yang disebut sistem panggilan jika ada yang gagal di sini.
1 Skenario yang dibayangkan oleh Matthew Ife dalam komentar untuk pertanyaan Anda terdengar sangat masuk akal di sini. Mengutipnya:
Saya menduga itu sedang mencari di akhir file untuk mendapatkan ukuran buffer untuk membaca data, menangani fakta bahwa pencarian tidak berfungsi dan berusaha untuk mengalokasikan ukuran negatif (tidak menangani malloc buruk). Melewati buffer untuk membaca kesalahan yang diberikan buffer tidak valid.