Memberitahu jika deskriptor file menunjuk ke perangkat terminal
Suatu program dapat mengetahui apakah deskriptor file dikaitkan dengan perangkat tty dengan menggunakan isatty()
fungsi C standar (yang umumnya di bawahnya melakukan ioctl()
panggilan sistem tty khusus yang tidak berbahaya yang akan kembali dengan kesalahan ketika fd tidak menunjuk ke perangkat tty) .
The [
/ test
utilitas dapat melakukannya dengan nya -t
operator.
if [ -t 1 ]; then
echo stdout is open to a terminal
fi
Melacak panggilan fungsi libc pada sistem GNU / Linux:
$ ltrace [ -t 1 ] | cat
[...]
isatty(1) = 0
[...]
Melacak panggilan sistem:
$ strace [ -t 1 ] | cat
[...]
ioctl(1, TCGETS, 0x7fffd9fb3010) = -1 ENOTTY (Inappropriate ioctl for device)
[...]
Memberitahu jika menunjuk ke pipa
Untuk menentukan apakah fd dikaitkan dengan pipa / fifo, seseorang dapat menggunakan fstat()
pemanggilan sistem , yang mengembalikan struktur yang st_mode
bidangnya berisi jenis dan izin file yang dibuka pada fd itu. The S_ISFIFO()
standar C makro dapat digunakan pada yang st_mode
lapangan untuk menentukan apakah fd adalah pipa / fifo.
Tidak ada utilitas standar yang dapat melakukan fstat()
, tetapi ada beberapa implementasi stat
perintah yang tidak kompatibel yang dapat melakukannya. zsh
's stat
builtin dengan stat -sf "$fd" +mode
yang mengembalikan mode sebagai representasi string yang karakter pertama mewakili jenis ( p
untuk pipa). GNU stat
dapat melakukan hal yang sama dengan stat -c %A - <&"$fd"
, tetapi juga harus stat -c %F - <&"$fd"
melaporkan jenisnya sendiri. Dengan BSD stat
: stat -f %St <&"$fd"
atau stat -f %HT <&"$fd"
.
Memberitahu jika itu bisa dicari
Aplikasi umumnya tidak peduli jika stdout adalah pipa. Mereka mungkin peduli bahwa itu dapat dicari (meskipun umumnya tidak memutuskan apakah akan buffer atau tidak).
Untuk menguji apakah fd dapat dicari (pipa, soket, perangkat tty tidak dapat dicari, file biasa dan sebagian besar perangkat blok umumnya), seseorang dapat mencoba lseek()
panggilan sistem relatif dengan offset 0 (sangat tidak berbahaya). dd
adalah utilitas standar yang merupakan antarmuka lseek()
tetapi tidak dapat digunakan untuk pengujian itu, karena implementasi tidak akan memanggil lseek()
sama sekali jika Anda meminta offset 0.
The zsh
dan ksh93
kerang memiliki builtin mencari operator meskipun:
$ 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
Menonaktifkan buffering
The script
perintah menggunakan sepasang pseudo-terminal untuk menangkap output dari sebuah program, sehingga stdout program (dan stdin dan stderr) akan menjadi perangkat pseudo-terminal.
Ketika stdout ke perangkat terminal, umumnya masih ada beberapa buffering, tetapi berbasis garis. printf
/ puts
dan co tidak akan menulis apa pun sampai karakter baris baru akan dihasilkan. Untuk jenis file lain, buffering adalah dengan blok (beberapa kilo byte).
Ada beberapa opsi untuk menonaktifkan buffering yang dibahas dalam sejumlah tanya jawab di sini (mencari unbuffer atau stdbuf , Tidak dapat mengalihkan reduksi output memberikan beberapa pendekatan) baik dengan menggunakan pseudo-terminal seperti yang dapat dilakukan oleh socat
/ script
/ expect
/ unbuffer
(sebuah expect
script) / zsh
's zpty
atau dengan menyuntikkan kode dalam executable untuk menonaktifkan buffering seperti yang dilakukan oleh GNU atau FreeBSD stdbuf
.