W
./binary < file
binary
Stdin to plik otwarty w trybie tylko do odczytu. Zauważ, że w bash
ogóle nie odczytuje pliku, po prostu otwiera go do odczytu na deskryptorze pliku 0 (stdin) procesu, w którym wykonuje binary
.
W:
./binary << EOF
test
EOF
W zależności od powłoki, binary
stdin będzie albo usuniętym plikiem tymczasowym (AT&T ksh, zsh, bash ...), który zawiera, test\n
jak tam umieszczony przez powłokę lub koniec odczytu potoku ( dash
, yash
; i powłoka zapisuje test\n
równolegle na drugim końcu rury). W twoim przypadku, jeśli używasz bash
, byłby to plik tymczasowy.
W:
cat file | ./binary
W zależności od powłoki, binary
stdin będzie albo końcem odczytu rury, albo jednym końcem pary gniazd, w którym kierunek zapisu został wyłączony (ksh93) i cat
zapisuje zawartość file
na drugim końcu.
Kiedy stdin jest zwykłym plikiem (tymczasowym lub nie), można go zobaczyć. binary
może przejść do początku lub końca, przewinąć do tyłu itp. Może także ioctl()s
odwzorować , wykonać kilka takich jak FIEMAP / FIBMAP (jeśli użyje <>
zamiast tego <
, może obciąć / dziurkować w nim itp.).
z drugiej strony pary rur i gniazd są środkami komunikacji międzyprocesowej, binary
oprócz read
danych niewiele można zrobić (chociaż są też pewne operacje, takie jak niektóre specyficzne dla rur, ioctl()
które można by na nich wykonać, a nie na zwykłych plikach) .
Większość czasu, to brakujące umiejętność seek
, która powoduje, aplikacje na niepowodzenie / skarżą się podczas pracy z rurami, ale może to być jakikolwiek inny wywołań systemowych, które obowiązują na zwykłych plików, ale nie na różnych typach plików (jak mmap()
, ftruncate()
, fallocate()
) . W Linuksie istnieje również duża różnica w zachowaniu, gdy otwierasz, /dev/stdin
gdy fd 0 jest w potoku lub w zwykłym pliku.
Istnieje wiele poleceń, które obecnie nie mogą zajmować się tylko możliwy do przeszukania plików, ale kiedy to przypadek, to nie jest na ogół za pliki otwarte na ich 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
musi odczytać indeks zapisany na końcu pliku, a następnie szukać w pliku, aby odczytać członków archiwum. Ale tutaj plik (zwykły w pierwszym przypadku, potok w drugim) jest podawany jako argument ścieżki do unzip
i unzip
sam się otwiera (zwykle na fd innym niż 0) zamiast dziedziczenia fd już otwartego przez rodzica. Nie odczytuje plików zip ze standardowego wejścia. Stdin jest najczęściej używany do interakcji użytkownika.
Jeśli uruchomisz to binary
bez przekierowania po zachęcie interaktywnej powłoki działającej w emulatorze terminali, binary
stdin zostanie odziedziczony po nadrzędnej powłoce, która sama odziedziczy go po nadrzędnej emulatorze terminali i będzie Urządzenie pty otwarte w trybie odczytu + zapisu (coś w stylu /dev/pts/n
).
Te urządzenia też nie są widoczne. Jeśli więc binary
działa poprawnie podczas pobierania danych z terminala, być może problem nie polega na szukaniu.
Jeśli ta 14 ma być błędem (kod błędu ustawiony przez nieudane wywołania systemowe), to w większości systemów byłoby to EFAULT
( Zły adres ). read()
Wywołanie systemowe nie powiedzie się z tego błędu, jeśli poprosił, aby przeczytać na adres pamięci, który nie jest zapisywalny. Byłoby to niezależne od tego, czy fd odczytuje dane z punktów do potoku lub zwykłego pliku i ogólnie wskazuje na błąd 1 .
binary
prawdopodobnie określa typ pliku otwartego na stdin (with fstat()
) i napotyka błąd, gdy nie jest to zwykły plik ani urządzenie tty.
Trudno powiedzieć, nie wiedząc więcej o aplikacji. Uruchomienie go pod strace
(lub truss
/ lub tusc
odpowiednikiem w twoim systemie) może pomóc nam zobaczyć, co to jest wywołanie systemowe, jeśli coś tutaj nie działa.
1 Scenariusz przewidziany przez Matthew Ife w komentarzu do twojego pytania brzmi tutaj bardzo realistycznie. Cytując go:
Podejrzewam, że szuka końca pliku, aby uzyskać rozmiar bufora do odczytu danych, źle radzi sobie z tym, że funkcja seek nie działa i próbuje przydzielić rozmiar ujemny (nie obsługuje złego malloc). Przekazywanie bufora w celu odczytania, które błędy w danym buforze są nieprawidłowe.