บอกว่าตัวบอกไฟล์ชี้ไปที่อุปกรณ์ปลายทาง
โปรแกรมสามารถบอกได้ว่า file descriptor เชื่อมโยงกับอุปกรณ์ tty หรือไม่โดยใช้isatty()
ฟังก์ชั่น C มาตรฐาน (ซึ่งโดยทั่วไปแล้วภายใต้การioctl()
เรียกระบบtty เฉพาะที่ไม่มีอันตรายซึ่งจะกลับมาพร้อมกับข้อผิดพลาดเมื่อ fd ไม่ได้ชี้ไปที่อุปกรณ์ tty) .
[
/ test
ยูทิลิตี้สามารถทำมันได้กับ-t
ผู้ประกอบการ
if [ -t 1 ]; then
echo stdout is open to a terminal
fi
การติดตามการเรียกใช้ฟังก์ชัน libc บนระบบ GNU / Linux:
$ ltrace [ -t 1 ] | cat
[...]
isatty(1) = 0
[...]
การติดตามการโทรของระบบ:
$ strace [ -t 1 ] | cat
[...]
ioctl(1, TCGETS, 0x7fffd9fb3010) = -1 ENOTTY (Inappropriate ioctl for device)
[...]
บอกถ้ามันชี้ไปที่ท่อ
ในการพิจารณาว่า fd นั้นเชื่อมโยงกับไพพ์ / ฟีฟ่าเราสามารถใช้การfstat()
เรียกของระบบซึ่งจะส่งกลับโครงสร้างของst_mode
ฟิลด์ที่มีประเภทและสิทธิ์ของไฟล์ที่เปิดใน fd นั้น S_ISFIFO()
มาตรฐาน C แมโครที่สามารถใช้กับที่st_mode
สนามเพื่อตรวจสอบว่า FD เป็นท่อ / FIFO
ไม่มียูทิลิตี้มาตรฐานที่สามารถทำได้fstat()
แต่มีการใช้งานที่ไม่สอดคล้องกันหลายประการของstat
คำสั่งที่สามารถทำได้ zsh
's stat
ในตัวด้วยstat -sf "$fd" +mode
ซึ่งผลตอบแทนโหมดเป็นตัวแทนสตริงที่มีตัวละครที่แสดงให้เห็นถึงชนิด (ครั้งแรกp
สำหรับท่อ) GNU stat
สามารถทำเช่นเดียวกันกับstat -c %A - <&"$fd"
ได้ แต่stat -c %F - <&"$fd"
ต้องรายงานประเภทเดียว ด้วย BSD stat
: หรือstat -f %St <&"$fd"
stat -f %HT <&"$fd"
บอกถ้ามันหาได้
แอ็พพลิเคชันโดยทั่วไปไม่สนใจว่า stdout เป็นไพพ์แม้ว่า พวกเขาอาจสนใจว่ามันหาได้ (แม้ว่าโดยทั่วไปแล้วจะไม่ตัดสินใจว่าจะบัฟเฟอร์หรือไม่)
เพื่อทดสอบว่า fd สามารถค้นหาได้ (ท่อ, ซ็อกเก็ต, อุปกรณ์ tty ไม่สามารถค้นหาได้, ไฟล์ปกติและอุปกรณ์บล็อกส่วนใหญ่โดยทั่วไป), หนึ่งสามารถลองการlseek()
เรียกระบบสัมพัทธ์กับออฟเซต 0 (ไร้เดียงสา) dd
เป็นยูทิลิตี้มาตรฐานที่เป็นอินเตอร์เฟสlseek()
แต่ไม่สามารถใช้สำหรับการทดสอบนั้นได้เนื่องจากการใช้งานจะไม่โทรlseek()
เลยหากคุณขอออฟเซ็ตเป็น 0
zsh
และksh93
เปลือกหอยมีในตัวที่กำลังมองหาผู้ประกอบการว่า:
$ 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
ปิดการใช้งานการบัฟเฟอร์
script
คำสั่งใช้คู่หลอกขั้วที่จะจับเอาท์พุทของโปรแกรมเพื่อ stdout โปรแกรม (และ stdin และ stderr) จะเป็นอุปกรณ์หลอกขั้ว
เมื่อ stdout ไปยังอุปกรณ์เทอร์มินัลโดยทั่วไปยังคงมีการบัฟเฟอร์บางส่วน แต่มันจะขึ้นอยู่กับสาย printf
/ puts
และ co จะไม่เขียนอะไรจนกว่าตัวอักขระบรรทัดใหม่จะถูกส่งออก สำหรับไฟล์ประเภทอื่น ๆ การบัฟเฟอร์จะแบ่งตามบล็อก (จากไม่กี่กิโลไบต์)
มีหลายตัวเลือกในการปิดการใช้งานบัฟเฟอร์ซึ่งถูกกล่าวถึงในจำนวนของคำถาม & ที่นี่ (ค้นหาunbufferหรือstdbuf , ไม่สามารถเปลี่ยนเส้นทางการส่งออกตัดให้วิธีการไม่กี่วิธี) โดยใช้เทอร์มินัลเทียมหลอกsocat
/ script
/ expect
/ unbuffer
(เป็นexpect
สคริปต์) / zsh
's zpty
หรือโดยการฉีดรหัสในการปฏิบัติการเพื่อปิดการใช้งานบัฟเฟอร์เป็นกระทำโดย GNU หรือของ stdbuf
FreeBSD