回答:
次のような関数をbash(またはPOSIXシェル)で使用できます。
grep() {
if [ -t 1 ] && [ -t 0 ]; then
command grep -n "$@"
else
command grep "$@"
fi
}
[ -t 1 ]
一部が使用[
コマンド(としても知られるtest
) STDOUTがTTYに関連付けられているかどうかをチェックします。
[ -t 0 ]
あなたがいる場合のみ、行番号を追加するために、指定するのでチェックし、標準入力だけでなく、grep
ある唯一のパイプラインでコマンド。
(完全を期すため)
一方で、@のenzotibの答えはおそらくあなたが望むものである、それはあなたが何を求めていないのです。[ -t 1 ]
ファイル記述子が端末デバイスであるかどうかをチェックします。パイプ以外のもの(通常のファイル、ソケット、その他のタイプのデバイスなど/dev/null
)ではありません
この[
コマンドには-t
、パイプ以外のものはありません。ファイル記述子に関連付けられているファイルの種類を取得するには、そのファイルに対してfstat()
システムコールを実行する必要があります。それを行うための標準コマンドはありませんが、一部のシステムまたはシェルにはいくつかあります。
GNUの場合stat
:
grep() {
if { [ "$(LC_ALL=C stat -c %F - <&3)" = fifo ]; } 3>&1 ||
[ "$(LC_ALL=C stat -c %F -)" = fifo ]; then
command grep "$@"
else
command grep -n "$@"
fi
}
またはzsh
、独自のstat
ビルトイン(数年前にGNUの1つより前のもの)を使用して、ここでzstat
のみロードされます:
grep() {
zmodload -F zsh/stat b:zstat
local stdin_type stdout_type
if zstat -A stdin_type -s -f 0 +mode &&
zstat -A stdout_type -s -f 1 +mode &&
[[ $stdin_type = p* || $stdout_type = p* ]]
then
command grep "$@"
else
command grep -n "$@"
fi
}
次に、いくつかのメモ:
パイプを使用するのはシェルパイプラインだけではありません。
var=$(grep foo bar)
または:
cmd <(grep foo bar)
または:
coproc grep foo bar
またgrep
、stdoutをパイプに接続して実行します。
シェルがの場合、ksh93
一部のシステムでは、パイプラインでパイプの代わりにソケットペアを使用することに注意してください。
[[ -t 0 && -t 1 ]]
、標準入力と標準出力の両方が端末に接続されている場合にのみ行番号が必要な場合は、テストを行います。