Trong
./binary < file
binary
Stdin là tập tin mở ở chế độ chỉ đọc. Lưu ý rằng bash
hoàn toàn không đọc tệp, nó chỉ mở tệp để đọc trên bộ mô tả tệp 0 (stdin) của quy trình mà nó thực hiện binary
.
Trong:
./binary << EOF
test
EOF
Tùy thuộc vào shell, binary
stdin của sẽ là một tệp tạm thời bị xóa (AT & T ksh, zsh, bash ...) có chứa test\n
như được đặt ở đó bởi shell hoặc đầu đọc của ống ( dash
, yash
; và shell ghi test\n
song song ở đầu kia của ống). Trong trường hợp của bạn, nếu bạn đang sử dụng bash
, nó sẽ là một tệp tạm thời.
Trong:
cat file | ./binary
Tùy thuộc vào vỏ, binary
stdin của nó sẽ là đầu đọc của ống hoặc một đầu của cặp ổ cắm nơi hướng viết đã bị tắt (ksh93) và cat
đang viết nội dung file
ở đầu kia.
Khi stdin là một tệp thông thường (tạm thời hoặc không), nó có thể tìm kiếm được. binary
có thể đi đến đầu hoặc cuối, tua lại, v.v. Nó cũng có thể tạo ra nó, làm một số thứ ioctl()s
như FIEMAP / FIBMAP (nếu sử dụng <>
thay vì <
, nó có thể cắt / đục lỗ trong đó, v.v.).
Mặt khác, các cặp ống và ổ cắm là một phương tiện giao tiếp giữa các quá trình, không binary
thể làm gì nhiều ngoài read
việc nhập dữ liệu (mặc dù cũng có một số thao tác như một số ống cụ thể ioctl()
mà nó có thể thực hiện trên chúng chứ không phải trên các tệp thông thường) .
Hầu hết các lần, đó là khả năng thiếu để seek
gây ra các ứng dụng để thất bại / phàn nàn khi làm việc với ống, nhưng nó có thể là bất kỳ của các cuộc gọi hệ thống khác có giá trị trên các tập tin thường xuyên nhưng không phải trên các loại khác nhau của các file (như mmap()
, ftruncate()
, fallocate()
) . Trên Linux, cũng có một sự khác biệt lớn về hành vi khi bạn mở /dev/stdin
trong khi fd 0 nằm trên một đường ống hoặc trên một tệp thông thường.
Có rất nhiều các lệnh ra khỏi đó mà chỉ có thể đối phó với seekable file, nhưng khi đó là trường hợp, đó là thường không cho các tập tin mở trên stdin của họ.
$ 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
cần đọc chỉ mục được lưu trữ ở cuối tệp, sau đó tìm trong tệp để đọc các thành viên lưu trữ. Nhưng ở đây, tệp (thông thường trong trường hợp đầu tiên, ống trong lần thứ hai) được đưa ra làm đối số đường dẫn đến unzip
và unzip
mở chính nó (thường là trên fd khác 0) thay vì kế thừa fd đã được mở bởi cha mẹ. Nó không đọc các tập tin zip từ stdin của nó. stdin chủ yếu được sử dụng cho tương tác người dùng.
Nếu bạn chạy cái binary
của bạn mà không chuyển hướng theo dấu nhắc của trình vỏ tương tác đang chạy trong trình giả lập thiết bị đầu cuối, thì binary
stdin của nó sẽ được thừa hưởng từ lớp vỏ của nó, chính nó sẽ được thừa hưởng từ trình giả lập thiết bị đầu cuối của nó và sẽ là một thiết bị pty mở ở chế độ đọc + ghi (đại loại như /dev/pts/n
).
Những thiết bị này cũng không thể tìm kiếm được. Vì vậy, nếu binary
hoạt động tốt khi lấy đầu vào từ thiết bị đầu cuối, có thể vấn đề không nằm ở việc tìm kiếm.
Nếu 14 đó có nghĩa là một lỗi (mã lỗi được đặt bằng cách không thực hiện các cuộc gọi hệ thống), thì trên hầu hết các hệ thống, đó sẽ là EFAULT
( Địa chỉ xấu ). Cuộc read()
gọi hệ thống sẽ thất bại với lỗi đó nếu được yêu cầu đọc vào một địa chỉ bộ nhớ không thể ghi. Điều đó sẽ độc lập với việc fd đọc dữ liệu từ các điểm đến một đường ống hoặc tệp thông thường và thường chỉ ra lỗi 1 .
binary
có thể xác định loại tệp mở trên stdin của nó fstat()
và gặp lỗi khi đó không phải là tệp thông thường cũng không phải là thiết bị tty.
Khó để nói mà không biết thêm về ứng dụng. Chạy nó bên dưới strace
(hoặc truss
/ tusc
tương đương trên hệ thống của bạn) có thể giúp chúng tôi xem hệ thống gọi là gì nếu có bất kỳ lỗi nào ở đây.
1 Kịch bản được Matthew Ife đưa ra trong một bình luận cho câu hỏi của bạn nghe có vẻ rất hợp lý ở đây. Trích dẫn anh ấy:
Tôi nghi ngờ nó đang tìm đến cuối tệp để có kích thước bộ đệm để đọc dữ liệu, xử lý không tốt thực tế là tìm kiếm không hoạt động và cố gắng phân bổ kích thước âm (không xử lý một malloc xấu). Truyền bộ đệm để đọc lỗi nào được cung cấp cho bộ đệm không hợp lệ.