1

を使用するこのプログラムがあります

ioctl(file_descriptor_of_stdout, TIOCGWINSZ, &w);

端末の幅を取得します (配列の印刷で使用されます)。プログラムを端末で直接実行すると、これは正常に機能します。ただし、ページングと検索のために、出力を less にパイプすることがよくあります。議論のために、stderr もパイプ処理されていると仮定します。そのため、実際に端末に送られることを期待して「ごまかす」ことはできません。

現在、 less 自体端末の幅を考慮しています - 行を分割したり切り落としたりするためです。この情報を何らかの方法で、パイプを介してパイプされているものにさらに伝達しませんか?

4

1 に答える 1

2

複数の選択肢があります:

  • 3 つのストリーム ( stdinstdout、およびstderr ) があり、プログラムは などを使用してチェックできますisatty(fileno(stdin))。対話型プログラムの出力のリダイレクトは、入力のリダイレクトよりも頻繁に行われるため、確認する価値があります。
  • どのストリームもターミナルでない場合は、すべてのインタラクティブプロセスttyに関連付けられている を開くことができます。で実行されているシェルからの簡単なチェックに示されているように、必ずしもそうとは限りません。/dev/ttyxterm
    $ ls -l /dev/tty;tty;ls -l `tty`
    crw-rw-rw- 1 ルート ルート 5、0 3 月 10 日 15:46 /dev/tty
    /dev/pts/1
    crw--w---- 1 tom tty 136, 1 Mar 10 16:09 /dev/pts/1
  • POSIXttyは、開始するのに適した場所と思われるプログラムを文書化しています。isattyただし、プログラムはパイプからパス名を読み取る必要があります (標準ストリームに適用されるよりも少し複雑です)。ドキュメントには次のようにも書かれています

    標準入力から入力が読み取られない間、標準入力が端末であるかどうかを判別し、そうである場合は端末の名前を判別するために、標準入力が検査されます。

    つまり、プログラムの標準入力が (端末でttyはなく) リダイレクトされる場合、実際の端末を見つけることは役に立ちません。
    @einpoklum によるコメントは、POSIX もライブラリ呼び出しを文書化していることを思い出させてくれましたttyname。ところで、通常、プログラムが特定の関数呼び出しによって実装される場合、POSIX はそのプログラムを文書化し、そのプログラムがその呼び出しを使用したかのように動作すると述べています。しかし、これについては言及されていませんでしたtty

  • 標準ストリームのいずれも端末でない場合は、開いてみることができ/dev/ttyます。プログラムが対話型でない場合、たとえばcronバックグラウンドで実行されているなど、失敗する可能性があります。奇妙な批判に思われないように、cron. 繰り返しになりますが、POSIX 文書 ( 10.1 のディレクトリ構造とファイル
于 2016-03-10T21:23:58.387 に答える