Nói nếu một bộ mô tả tập tin trỏ đến một thiết bị đầu cuối
Một chương trình có thể cho biết nếu một bộ mô tả tệp được liên kết với một thiết bị tty bằng cách sử dụng isatty()chức năng C tiêu chuẩn (thường nằm bên dưới một ioctl()cuộc gọi hệ thống cụ thể vô hại sẽ trả về lỗi khi fd không trỏ đến thiết bị tty) .
Các [/ testtiện ích có thể làm điều đó với mình -tđiều hành.
if [ -t 1 ]; then
echo stdout is open to a terminal
fi
Truy tìm hàm libc trên hệ thống GNU / Linux:
$ ltrace [ -t 1 ] | cat
[...]
isatty(1) = 0
[...]
Truy tìm hệ thống theo dõi:
$ strace [ -t 1 ] | cat
[...]
ioctl(1, TCGETS, 0x7fffd9fb3010) = -1 ENOTTY (Inappropriate ioctl for device)
[...]
Nói nếu nó chỉ vào một đường ống
Để xác định xem fd có được liên kết với ống / fifo hay không, người ta có thể sử dụng lệnh fstat()gọi hệ thống , trả về cấu trúc có st_modetrường chứa loại và quyền của tệp được mở trên fd đó. Các S_ISFIFO()C macro tiêu chuẩn có thể được sử dụng trên đó st_modelĩnh vực để xác định xem fd là một ống / FIFO.
Không có tiện ích tiêu chuẩn nào có thể làm được fstat(), nhưng có một số cách triển khai statlệnh không tương thích có thể thực hiện được. zshNội dung statdựng sẵn stat -sf "$fd" +modetrả về chế độ dưới dạng chuỗi đại diện có ký tự đầu tiên đại diện cho loại ( pđối với đường ống). GNU statcó thể làm tương tự với stat -c %A - <&"$fd", nhưng cũng stat -c %F - <&"$fd"phải báo cáo loại một mình. Với BSD stat: stat -f %St <&"$fd"hoặc stat -f %HT <&"$fd".
Nói nếu nó có thể tìm kiếm
Các ứng dụng thường không quan tâm nếu thiết bị xuất chuẩn là một đường ống. Họ có thể quan tâm rằng nó có thể tìm kiếm được (mặc dù thường không quyết định có đệm hay không).
Để kiểm tra xem fd có thể tìm kiếm được không (ống, ổ cắm, thiết bị tty không thể tìm kiếm, các tệp thông thường và hầu hết các thiết bị khối thường là), người ta có thể thử một lseek()cuộc gọi hệ thống tương đối với độ lệch bằng 0 (rất vô hại). ddlà một tiện ích tiêu chuẩn có giao diện lseek()nhưng nó không thể được sử dụng cho thử nghiệm đó, vì việc triển khai sẽ hoàn toàn không gọi lseek()nếu bạn yêu cầu bù 0.
Các shell zshvà ksh93shell đã tích hợp sẵn các toán tử tìm kiếm:
$ strace -e lseek ksh -c ': 1>#((CUR))' | cat
lseek(1, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek)
ksh: 1: not seekable
$ strace -e lseek zsh -c 'zmodload zsh/system; sysseek -w current -u 1 0 || syserror'
lseek(1, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek)
Illegal seek
Vô hiệu hóa bộ đệm
Các scriptlệnh sử dụng một cặp giả thiết bị đầu cuối để bắt đầu ra của một chương trình, do đó chương trình stdout (và stdin và stderr) sẽ là một thiết bị giả thiết bị đầu cuối.
Khi thiết bị xuất chuẩn là thiết bị đầu cuối, nhìn chung vẫn có một số bộ đệm, nhưng nó dựa trên dòng. printf/ putsvà đồng sẽ không viết bất cứ điều gì cho đến khi một ký tự dòng mới được xuất ra. Đối với các loại tệp khác, bộ đệm là theo khối (của một vài kilo byte).
Có một số tùy chọn để vô hiệu hóa bộ đệm được thảo luận trong một số câu hỏi và hỏi đáp ở đây (tìm kiếm unbuffer hoặc stdbuf , không thể chuyển hướng cắt đầu ra đưa ra một vài cách tiếp cận) bằng cách sử dụng thiết bị đầu cuối giả như có thể được thực hiện bởi socat/ script/ expect/ unbuffer(một expecttập lệnh) / zsh's zptyhoặc bằng cách tiêm mã vào tệp thực thi để vô hiệu hóa bộ đệm như được thực hiện bởi GNU hoặc FreeBSD stdbuf.