4

Поэтому я работаю над сценарием и обнаружил странное поведение. Я уверен, что есть логическое объяснение, почему выходные данные 4- й и 6- й командной строки отличаются от других случаев, но я не могу их найти.

1 $ tput cols
128

2 $ tput cols 2>/dev/null
128

3 $ echo $(tput cols)
128

4 $ echo $(tput cols 2>/dev/null)
80

5 $ (tput cols >/tmp/cols.txt); cat /tmp/cols.txt
128

6 $ (tput cols &>/tmp/cols.txt); cat /tmp/cols.txt
80

7 $ echo $(tput cols 2>/dev/null; echo $COLUMNS; tput cols)
80 128 128

Почему перенаправление stderr изменяет вывод tput в подоболочке?

В конечном итоге я хочу сделать что-то подобное в моем скрипте, чтобы он работал в системах, где tput/ncurses недоступен:

cols=$(tput cols 2>/dev/null || echo $COLUMNS)

Пример выше был создан с использованием Bash 4.3.46(1)-релизов и ncurses 6.0.20150627

1 ответ1

2

Согласно strace , это происходит потому, что tput пытается только прочитать настройки tty из своих stdout и stderr (fd 1 & 2). Поскольку вы явно перенаправили stderr, а $( ) также перенаправляет stdout, tput сдается.

Лучшим решением было бы исправление tput, чтобы также проверить stdin на наличие tty; однако вы также можете просто удалить перенаправление 2>/dev/null , так как tput cols никогда не выводит никаких сообщений об ошибках. (И если он выводит некоторые сообщения об ошибках, лучше обратить на них внимание.)

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .