stdin ? command : pipe

コマンドからパイプで渡されたデータはどう処理するのだろう?
どうせ stdin だろう、サクッと Python で実験

#!/usr/bin/env python3

# if stdin != pipe:
#     Press Ctrl+D

import sys
print(sys.argv)
print(sys.stdin.read())

pypipe

普通に stdin に入ってくるので値を得るのは簡単。
だけどうっかり単独起動すると当然のように入力待ちになる。
なので強制終了するしかない、cat コマンドもそうなるね。

でも bc コマンドなんかはパイプ経由だと計算結果を出力のみ。
単独起動だとインタラクティブシェルにと振り分けされる。
何か方法はあるのだろう、検索検索。

シェルスクリプトでパイプからの入力とキーボード入力を区別する

シェルスクリプトなら上記リンク先の方法で振り分けできた。
ファイルディスクプリタで見分けるのか、おぉワカラン。

LinuxやUNIXでパイプで渡されたデータをC言語で適切に処理するには? – Yahoo!知恵袋

やっぱりファイルディスクリプタか。
Non-blocking I/O がどうかでなく振り分けがしたいだけなんですが。
これはこれで勉強になるのでブックマークと。

面倒だ、bc のソースを読んでしまえ。
結構利用しているけどもう 15 年もメンテされていなかったのか…
http://ftp.gnu.org/gnu/bc/

grep しまくって isatty という関数を見つけた。
UNIXの部屋 コマンド検索:isatty (*BSD/Linux)

コレだよコレ。
STDOUT_FILENO はどうせ enum だし in 側はゼロだろ、ならば。

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

int
main (int argc, char* argv[]) {
    if (isatty(0)) {
        printf("stdin == Console\n");
    } else {
        char pipe[256];
        fgets(pipe, 256, stdin);
        printf(pipe);
    }
    return 0;
}

isatty

こんなにアッサリと振り分けできるじゃない。
マネしただけなんですが。
いやぁ GPL って本当に素晴らしいですね。