(для полноты)
Хотя ответ @ 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 один на несколько лет), здесь загружается как 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 ]]
если вам нужны только номера строк, если и стандартный вход, и стандартный выход подключены к терминалу.