Перенаправление stderr в subshell изменяет вывод tput
Поэтому я работаю над сценарием и обнаружил странное поведение. Я уверен, что есть логическое объяснение, почему выходные данные 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 ответ
В соответствии с strace
это происходит потому, что tput
только пытается прочитать настройки tty из своих stdout и stderr (fd 1 & 2). Так как вы явно перенаправили stderr, и $( )
также перенаправляет стандартный вывод, tput сдается.
Лучшим решением было бы исправить tput, чтобы он также проверял наличие стандартного ввода в tdin; Тем не менее, вы также можете просто удалить 2>/dev/null
перенаправить, так как tput cols
в любом случае никогда не выводит никаких сообщений об ошибках. (И если он выводит некоторые сообщения об ошибках, лучше обратить на них внимание.)