Pracuję nad skryptem i znalazłem dziwne zachowanie. Jestem pewien, że istnieje logiczne wytłumaczenie, dlaczego wyjście 4 -go i 6 -go wiersza poleceń jest inna niż w innych przypadkach, ale nie udało mi się go znaleźć.
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
Dlaczego przekierowanie stderr zmienia wyjście tput w podpowłoce?
Ostatecznie chcę zrobić coś takiego w moim skrypcie, aby działał na systemach, w których tput / ncurses nie jest dostępny:
cols=$(tput cols 2>/dev/null || echo $COLUMNS)
Powyższy przykład został stworzony przy użyciu wersji Bash 4.3.46 (1) i ncurses 6.0.20150627
Odpowiedzi:
Zgodnie z
strace
tym dzieje się tak, ponieważtput
próbuje tylko odczytać ustawienia tty z jego stdout i stderr (fd 1 i 2). Ponieważ wyraźnie przekierowałeś stderr, a$( )
także przekierowuje stdout, tput się poddaje.Najlepszym rozwiązaniem byłoby załatanie tput, aby sprawdzić także stdin na obecność tty; możesz jednak po prostu usunąć
2>/dev/null
przekierowanie, ponieważ i taktput cols
nigdy nie wyświetla żadnych komunikatów o błędach. (A jeśli wygenerował jakieś komunikaty o błędach, najlepiej jest na nie zwrócić uwagę.)źródło