13

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

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

Итак, предположим, что имя файла 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
  • В соответствии сthis, tty может не поддерживать-s вариант. Так что либо используйте[ -t N ]или перенаправить вывод на/dev/null.

    от
  • И, если вы хотите проверить стандартный вывод, а не стандартный ввод, выполнитеtty < /dev/fd/1.

    от
  • (Если вас интересует конкретика, вот сообщение, которое оно дает:SC2166: Prefer [ p ] && [ q ] as [ p -a q ] is not well defined.)

    от
  • Shellcheck говорит[a] && [b] является более портативным, чем[a -a b], хоть.

    от
  • В качестве дополнения, поскольку в вопросе явно упоминается Bash, это предпочтительный способ:[[ -t 0 ]] (и / или 1, в зависимости от того, хотите ли вы проверить, подключен ли stdin и / или stdout к терминалу), потому что[[ ]] является встроенной командой Bash, а[ ] порождает внешний процесс.

    от
  • Спасибо, что поделился. Это кажется хорошей идеей. Иногда меньше - больше, иногда меньше - меньше. Итак ... Это новая парадигма в сценариях оболочки, о которой я не знаю, или ваше личное мнение? Всем удачи.

    от
  • @DanielYCLin,[ (акаtest) имеет встроенные & quot; и & quot; & # X2014;-a

    от
  • для лучшего ответа будетif [ -t 0 ] && [ -t 1 ]

    от Daniel YC Lin
  • Ваш образец подходит дляstdin Чехол дляstdout, мы можем использоватьif [ -t 1 ].

    от Daniel YC Lin
  • спасибо, ваш ответ правильный, но следующий ответ яснее.

    от Daniel YC Lin
  • 8

    От -t FD True if FD is opened on a terminal.

    Отhelp test:

     -t FD          True if FD is opened on a terminal.
    

  • 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
    

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

  • 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
    

  • 6

    Вы могли бы использовать if tty -s then # ... fi

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

    if tty -s
    then
        # ...
    fi
    

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