2012-04-02 27 views
3

我想當前終端的尺寸,即,在端子我的Perl腳本在運行以下應該做的工作:

#!/usr/bin/perl 

sub getTerminalSize { 
    my @dimensions = (24,80); 
    open(my $OH, '-|', "/usr/bin/tput lines ; /usr/bin/tput cols") 
     || return @dimensions; 
    chomp(@dimensions = <$OH>); 
    close($OH); 
    return @dimensions; 
} 

open (STDERR, ">>bla.log") or die "can not create logfile"; 
print "Dimensions of your terminal: ". (join " x " , getTerminalSize()) ."\n"; 

沒有倒數的一行代碼它的作品,因爲它應該。 但是對於這條線,我總是得到24 x 80,所以它似乎在內部創建了一個新的shell,並返回了該shell的大小。只是我的猜測。 那麼究竟發生了什麼以及如何獲得兩者 - 重定向STDERR和正確的大小?

+0

這是一個Perl FAQ:[我如何獲得屏幕尺寸?](http://learn.perl.org/faq/perlfaq8.html#How-do-I-get-the-screen-size-) – daxim 2012-04-02 19:36:05

回答

3

對於tput來標識終端大小,其中一個文件描述符( stdin)stdout或stderr必須打開並連接到終端。

在管道結構中,stdout連接到管道;如果將stderr重定向到一個文件,則tput將返回默認大小,因爲它不會分析stdin

因此,tput沒有終端可以使用;它返回默認大小24x80。


可以解決此問題通過增加2>/dev/ttytput命令:

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,但這是一個管道),而不是stdinfstat是一種自制命令,類似於stat,但它有不同的輸出格式。

+0

那麼,上面的腳本是完整的,即獨立,所以我不知道我在哪裏操縱stdin? – 2012-04-02 12:28:40

+0

迄今爲止非常感謝。但作爲一個相當perl新手這個問題:如何「修復」這一點。我如何使自己的日常行爲按照預期行事(獨立於「環境」)? – 2012-04-02 12:42:03

+1

查看更多內容 - '輸入cols 2>/dev/tty'等 – 2012-04-02 12:46:52

相關問題