Я знаю, что для bash и zsh можно использовать, например. [ -t 1 ]
чтобы определить, является ли STDIN интерактивным сеансом tty.
Однако, похоже, нет способа проверить, перенаправляется ли stdin из файла или передается из команды:
foo < ./file
bar | foo
Есть ли способ обнаружить разницу между этими двумя? Отдельно, есть ли способ получить путь к перенаправляемому файлу (вне /proc/self, который недоступен в macOS)?
Вы можете проверить, является ли /dev/stdin
обычным файлом или каналом:
$ cat tmp.sh
#!/bin/bash
if [ -f /dev/stdin ]; then
echo "file"
elif [ -p /dev/stdin ]; then
echo "pipe"
fi
$ bash tmp.sh < foo.txt
file
$ echo foo | bash tmp.sh
pipe
Однако это зависит от того, находится ли /dev/stdin
в вашей файловой системе.
Вы также можете использовать команду stat
, которая вернет информацию о стандартном вводе без аргумента имени файла. Как вы упомянули, что используете macOS, вы можете использовать формат %HT
:
$ stat -f %HT
Character Device
$ stat -f %HT < foo.txt
Regular File
$ echo foo | stat -f %HT
Fifo File
«Bash обрабатывает несколько имен файлов специально, когда они используются в перенаправлениях», включая /dev/stdin
Однако -f /dev/stdin
не является перенаправлением.
Какой ответ вы ожидаете, если ./file является именованным каналом?