Чтобы tput
идентифицировал размер терминала, один из файловых дескрипторов для ( stdin ,) stdout или stderr должен быть открыт и подключен к терминалу.
В конструкции трубы stdout
подключается к трубе; если вы перенаправляете stderr
в файл, то tput
возвращает размер по умолчанию, поскольку он не анализирует stdin
.
Итак, tput
не имеет терминала для работы; он возвращает размер по умолчанию 24x80.
Вы можете обойти эту проблему, добавив 2>/dev/tty
к командам tput
:
open my $OH, '-|', "/usr/bin/tput lines 2>/dev/tty; /usr/bin/tput cols 2>/dev/tty"
or return @dimensions;
Похоже, что tput
вообще не смотрит на stdin
. (Перенаправление stdout
на терминал может привести к потере конвейерного механизма, который Perl использует для чтения информации.)
$ tput lines </dev/null
65
$ tput lines </dev/null 2>/dev/null
65
$ x=$(tput lines </dev/null 2>/dev/null)
$ echo $x
24
$
Я добавил диагностическую распечатку в функцию, чтобы убедиться, что она считывает вывод с tput
, и это было. Я добавил эти строки в функцию:
open( my $OH, '-|', "fstat /dev/fd/0 /dev/fd/1 /dev/fd/2 /dev/null")
or die "horribly";
my(@data) = <$OH>;
close($OH);
print @data;
и вывод был:
Mode Inode Links UID GID Size Modtime Dev RDev File
0020620 623 1 503 4 0 1333369875 334992488 268435457 /dev/fd/0
0010660 590945904 0 503 20 0 1333369875 334992488 0 /dev/fd/1
0100644 111429666 1 503 20 0 1333369875 334992488 0 /dev/fd/2
0020666 304 1 0 0 0 1333359963 334992488 50331650 /dev/null
При запуске в командной строке выдается:
$ fstat /dev/fd/[012] /dev/null
Mode Inode Links UID GID Size Modtime Dev RDev File
0020620 623 1 503 4 0 1333370018 334992488 268435457 /dev/fd/0
0020620 623 1 503 4 0 1333370018 334992488 268435457 /dev/fd/1
0020620 623 1 503 4 0 1333370018 334992488 268435457 /dev/fd/2
0020666 304 1 0 0 0 1333359963 334992488 50331650 /dev/null
$
Итак, стандартный ввод tput
все еще был терминалом, но tput
не смотрел на это. Следовательно, tput
, должно быть, смотрел на stderr
(неясно, пробовал ли он stdout
, но это была труба), а не на stdin
. fstat
- это команда домашнего приготовления, по духу похожая на stat
, но она имеет другой формат вывода.