Вопрос по shell, bash – проверьте isatty в bash

13

Я хочу, чтобы моя оболочка определяла поведение человека, а затем показывала подсказку.

Итак, предположим, что имя файла test.bash

#!/bin/bash
if [ "x" != "${PS1:-x}" ] ;then
 read -p "remove test.log Yes/No" x
 [ "$x" = "n" ] && exit 1
fi
rm -f test.log

Но я обнаружил, что это не может работать, если я не установил PS1. Есть ли лучший метод?

мои методы испытаний:

./test.bash                  # human interactive
./test.bash > /tmp/test.log  # stdout in batch mode
ls | ./test.bash             # stdin in batch mode

Ваш Ответ

4   ответа
6

Вы могли бы использовать/usr/bin/tty программа:

if tty -s
then
    # ...
fi

Я признаю, что я не уверен, насколько он переносим, но это, по крайней мере, часть ядра GNU coreutils.

И, если вы хотите проверить стандартный вывод, а не стандартный ввод, выполнитеtty < /dev/fd/1.
В соответствии сthis, tty может не поддерживать-s вариант. Так что либо используйте[ -t N ]или перенаправить вывод на/dev/null.
31

 if [ -t 0 ] ; then
    # this shell has a std-input, so we're not in batch mode 
   .....
 else
    # we're in batch mode

    ....
 fi

Надеюсь, это поможет.

для лучшего ответа будетif [ -t 0 ] && [ -t 1 ] Daniel YC Lin
В качестве дополнения, поскольку в вопросе явно упоминается Bash, это предпочтительный способ:[[ -t 0 ]] (и / или 1, в зависимости от того, хотите ли вы проверить, подключен ли stdin и / или stdout к терминалу), потому что[[ ]] является встроенной командой Bash, а[ ] порождает внешний процесс.
Ваш образец подходит дляstdin Чехол дляstdout, мы можем использоватьif [ -t 1 ]. Daniel YC Lin
@DanielYCLin,[ (акаtest) имеет встроенные & quot; и & quot; & # X2014;-a
Спасибо, что поделился. Это кажется хорошей идеей. Иногда меньше - больше, иногда меньше - меньше. Итак ... Это новая парадигма в сценариях оболочки, о которой я не знаю, или ваше личное мнение? Всем удачи.
8

Отhelp test:

 -t FD          True if FD is opened on a terminal.
спасибо, ваш ответ правильный, но следующий ответ яснее. Daniel YC Lin
2

Обратите внимание, что нет необходимости использовать говядины&& а также|| операторы оболочки для объединения двух отдельных прогонов[ команда, потому что[ команда имеет свой встроенныйand -a а такжеor -o операторы, позволяющие объединить несколько простых тестов в один результат.

Итак, вот как вы можете реализовать тест, который вы запросили & # x2014; где вы переходите в пакетный режим, еслиeither входor вывод был перенаправлен из TTY & # x2014; используя один вызов[:

if [ -t 0 -a -t 1 ]
then
    echo Interactive mode
else
    echo Batch mode
fi
Shellcheck говорит[a] && [b] является более портативным, чем[a -a b], хоть.
(Если вас интересует конкретика, вот сообщение, которое оно дает:SC2166: Prefer [ p ] && [ q ] as [ p -a q ] is not well defined.)

Похожие вопросы