ファイル記述子が端末デバイスを指しているかどうかを伝える
プログラムは、isatty()
標準のC関数を使用して、ファイル記述子がttyデバイスに関連付けられているかどうかを確認できます(通常はioctl()
、fdがttyデバイスを指していないときにエラーを返す無害なtty固有のシステムコールを行います) 。
[
/ test
ユーティリティはでそれを行うことができます-t
演算子。
if [ -t 1 ]; then
echo stdout is open to a terminal
fi
GNU / Linuxシステムでのlibc関数呼び出しのトレース:
$ ltrace [ -t 1 ] | cat
[...]
isatty(1) = 0
[...]
システムコールのトレース:
$ strace [ -t 1 ] | cat
[...]
ioctl(1, TCGETS, 0x7fffd9fb3010) = -1 ENOTTY (Inappropriate ioctl for device)
[...]
パイプを指しているかどうかを知る
fdがパイプ/ fifoに関連付けられているかどうかを判断するには、fstat()
システムコールを使用st_mode
して、そのfdで開かれたファイルのタイプと権限を含むフィールドを持つ構造体を返します。S_ISFIFO()
標準Cマクロは、その上で使用できるst_mode
FDがFIFO /パイプであるかどうかを決定するフィールド。
を実行できる標準ユーティリティはありませんがfstat()
、それを実行stat
できるコマンドの互換性のない実装がいくつかあります。zsh
の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
インターフェースである標準ユーティリティですが、オフセット0を要求するlseek()
と実装はまったく呼び出さlseek()
れないため、そのテストには使用できません。
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は、改行文字が出力されるまで何も書き込みません。他の種類のファイルの場合、バッファリングはブロック単位(数キロバイト)です。
ここでQ&Asの数で議論されているバッファリングを無効にするには、いくつかのオプションがあります(を検索バッファー解除またはstdbufは、缶リダイレクトないカット出力は、いくつかのアプローチを与える)ことによって行うことができるよう疑似端末を使用して、どちらかsocat
/ script
/ expect
/ unbuffer
(expect
スクリプト)/ zsh
さんzpty
またはGNUの又はFreeBSDのにより行われるようにバッファリングを無効にするために実行可能のコードを注入することによりstdbuf
。