Перенаправление stderr в subshell изменяет вывод tput

635
816-8055

Поэтому я работаю над сценарием и обнаружил странное поведение. Я уверен, что есть логическое объяснение, почему выходные данные 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.

4
У меня нет этого на моем rapsberry, однако, число столбцов может отличаться, когда вывод не является интерактивным (например, файл или / dev / null) Archemar 7 лет назад 0

1 ответ на вопрос

2
grawity

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

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

Да, это может быть так. Мне нужно подавить ошибку в случае, если tput не доступен. В качестве обходного пути я делаю это: if tput cols &> / dev / null; тогда cols = $ (tput cols), иначе cols = $ COLUMNS fi 816-8055 7 лет назад 0

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