В
./binary < file
binarysdin - це файл, відкритий у режимі лише для читання. Зауважте, що bashфайл взагалі не читає, він просто відкриває його для читання на дескрипторі файлів 0 (stdin) процесу, який він виконує binary.
В:
./binary << EOF
test
EOF
Залежно від оболонки, binarystdin буде або видаленим тимчасовим файлом (AT&T ksh, zsh, bash ...), який містить test\nяк розміщений туди оболонку, або зчитувальний кінець труби ( dash, yashі оболонка пише test\nпаралельно на іншому кінці труби). У вашому випадку, якщо ви використовуєте bash, це буде тимчасовий файл.
В:
cat file | ./binary
Залежно від оболонки, binarystdin буде або зчитувальним кінцем труби, або одним кінцем пари розетки, де напрямок запису було вимкнено (ksh93) і catзаписує вміст fileна іншому кінці.
Коли stdin - це звичайний файл (тимчасовий чи ні), його можна знайти. binaryможе йти на початок або в кінець, перемотати назад тощо. Це також може зробити ioctl()sкарту , зробити це на зразок FIEMAP / FIBMAP (якщо використовувати <>замість цього <, він може урізати / пробити отвори в ньому тощо).
З іншого боку, труби та пари розеток є міжпроцесорним засобом зв’язку, binaryокрім readданих не можна багато чого зробити (хоча є й деякі операції, як-от певні конкретні труби ioctl(), які вони можуть робити на них, а не на звичайних файлах) .
У більшості випадків, це відсутню здатність , seekщо призводить до додатків до збою / скаржаться при роботі з трубами, але це може бути будь-який з інших системних викликів, які дійсні для звичайних файлів , але не на різних типах файлів (як mmap(), ftruncate(), fallocate()) . У Linux також є велика різниця в поведінці, коли ви відкриваєте, /dev/stdinколи fd 0 знаходиться на трубі або у звичайному файлі.
Існує багато команд, які можуть працювати лише з файлами, які шукаються , але коли це так, це, як правило, не для файлів, відкритих на їхньому stdin.
$ 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потрібно прочитати індекс, що зберігається в кінці файлу, а потім шукати всередині файлу для читання членів архіву. Але тут файл (регулярний у першому випадку, труба у другому) задається як аргумент шляху до unzipта unzipвідкриває його сам (як правило, на fd, крім 0) замість успадкування вже відкритого батьком fd. Він не читає поштові файли зі свого stdin. stdin здебільшого використовується для взаємодії з користувачем.
Якщо ви запускаєте цю binaryсвою без перенаправлення під запит інтерактивної оболонки, що працює в емуляторі терміналу, то binarystdin буде успадкований від свого батьківського оболонки, який сам успадкував його від свого батьківського термінального емулятора і буде pty пристрій відкрито в режимі читання + запису (щось подібне /dev/pts/n).
Ці пристрої також не можна знайти. Отже, якщо binaryпрацює нормально, коли приймається вхід з терміналу, можливо, питання не в тому, щоб шукати.
Якщо це 14 мається на увазі помилка (код помилки, встановлений невдачею системних викликів), то для більшості систем це буде EFAULT( неправильна адреса ). read()Системний виклик зазнає невдачі з цією помилкою , якщо попросив прочитати на адресу пам'яті , який не доступний для запису. Це не залежатиме від того, чи буде fd читати дані з пунктів до труби чи звичайного файлу, і загалом би вказувало на помилку 1 .
binaryможливо, визначає тип файлу, відкритого на його stdin (with fstat()), і потрапляє в помилку, коли він не є ні звичайним файлом, ні tty пристроєм.
Важко сказати, не знаючи більше про додаток. Запуск його під strace(або truss/ tuscеквівалент у вашій системі) може допомогти нам зрозуміти, що таке системний виклик, якщо якийсь тут не працює.
1 Сценарій, передбачений Метью Іфе у коментарі до вашого питання, тут звучить дуже правдоподібно. Цитуючи його:
Я підозрюю, що він прагне до кінця файлу отримати розмір буфера для зчитування даних, погано поводячись з тим, що пошук не працює, і намагається виділити негативний розмір (не обробляючи поганий malloc). Передача буфера, щоб прочитати, які помилки в даному буфері не є дійсними.