シェルスクリプトで標準入出力が端末なのかパイプなのかリダイレクトなのかを判定するには

標準入力の判定

if [ -t 0 ]; then
    # 標準入力が端末の場合
    ....
elif [ -p /dev/stdin ]; then
    # 標準入力がパイプの場合
    ....
elif [ -f /dev/stdin ]; then
    # 標準入力が通常のファイルの場合 (シンボリックリンクでもリンク先が通常のファイルならOK)
    ....
else
    # 標準入力がそれ以外
    ....
fi

標準出力の判定

if [ -t 1 ]; then
    # 標準出力が端末の場合
    ....
elif [ -p /dev/stdout ]; then
    # 標準出力がパイプの場合
    ....
elif [ -f /dev/stdout ]; then
    # 標準出力が通常のファイルの場合 (シンボリックリンクでもリンク先が通常のファイルならOK)
    ....
else
    # 標準出力がそれ以外
    ....
fi

標準エラー出力の判定

if [ -t 2 ]; then
    # 標準エラー出力が端末の場合
    ....
elif [ -p /dev/stderr ]; then
    # 標準エラー出力がパイプの場合
    ....
elif [ -f /dev/stderr ]; then
    # 標準エラー出力が通常のファイルの場合 (シンボリックリンクでもリンク先が通常のファイルならOK)
    ....
else
    # 標準出力がそれ以外
    ....
fi

-t はそのファイルディスクリプタが端末かどうかを判定するオプション。

-p はそのファイルパスが名前付きパイプかどうかを判定するオプション。

シェルスクリプトを sh ./foo.sh | another_command のように起動した場合には標準出力がパイプだと判定される。

sh ./foo.sh > output.txt だと標準出力は通常のファイルだと判定される。

/dev/stdin/dev/stdout はどの環境でもつかえるものなのかは未確認。Ubuntu や CentOS では使えた。

このサイトは筆者(hydrocul)の個人メモの集合です。すべてのページは永遠に未完成です。
スポンサーリンク