端くれプログラマの備忘録 Unix [Unix] isatty()関数の使いどころ

[Unix] isatty()関数の使いどころ

C言語の isatty() 関数は、指定されたファイル記述子 (file descriptor) が端末(tty: teletype terminal)に関連付けられているかどうかを判定するための関数です。この関数は unistd.h ヘッダーで定義されています。

機能と使用方法

プロトタイプ

#include <unistd.h>

int isatty(int fd);

引数

  • fd: 判定対象のファイル記述子(例: 標準入力、標準出力、標準エラー出力、またはファイルやソケットの記述子)。

戻り値

  • 1 (真): fd が端末(tty)に関連付けられている場合。
  • 0 (偽): fd が端末に関連付けられていない場合。
  • -1: エラーが発生した場合(例: 無効なファイル記述子)。

主な用途

  1. インタラクティブな動作の判定
  • プログラムが端末から実行されているか、リダイレクトやパイプ経由で実行されているかを判定する。
  1. 動的な出力制御
  • 端末上ならカラーやフォーマットを使用し、ファイルにリダイレクトされた場合はプレーンテキストを出力するなどの制御。

サンプルコード

基本的な使用例

以下の例では、標準入力が端末からの入力かどうかを判定します。

#include <stdio.h>
#include <unistd.h>

int main() {
    if (isatty(STDIN_FILENO)) {
        printf("Standard input is a terminal.\n");
    } else {
        printf("Standard input is not a terminal.\n");
    }
    return 0;
}
  • STDIN_FILENO: 標準入力のファイル記述子(通常は0)。
  • 実行例:
  • 端末から実行: ./a.out
    Standard input is a terminal.
  • ファイルをリダイレクトして実行: ./a.out < input.txt
    Standard input is not a terminal.

応用例: 動的なフォーマット変更

端末上ではカラフルな出力をし、リダイレクトされた場合はシンプルな出力にする例です。

#include <stdio.h>
#include <unistd.h>

int main() {
    if (isatty(STDOUT_FILENO)) {
        printf("\033[32mHello, terminal!\033[0m\n"); // 緑色のテキスト
    } else {
        printf("Hello, plain text.\n"); // リダイレクト用のテキスト
    }
    return 0;
}
  • リダイレクトされていない場合:
  Hello, terminal!  (緑色で出力)
  • リダイレクトされている場合:
  Hello, plain text.

主なファイル記述子

isatty() によく使われる標準的なファイル記述子は以下の通りです。

記述子定義説明
STDIN_FILENO0標準入力
STDOUT_FILENO1標準出力
STDERR_FILENO2標準エラー出力

注意点

  1. パイプやリダイレクトが関与する場合
  • isatty() はパイプやリダイレクトされたファイル記述子に対しては 0 を返します。
  • 例: echo "test" | ./a.out の場合、標準入力は端末ではなくパイプに接続されています。
  1. エラー処理
  • 無効なファイル記述子(例: 負の値)を渡すとエラーになります。
  • 必要に応じてエラーメッセージを出力することを推奨します。

isatty() 関数を使用すると、プログラムをインタラクティブかつ柔軟に動作させることが可能になります。これは、CLIツールやログ出力制御などにおいて特に有用です。