2013-04-14 104 views
0
#!/usr/bin/env perl 

use Term::ReadKey; 
ReadMode 4; 
END { 
    ReadMode 0; # Reset tty mode before exiting 
} 

while (<>) { 
    $key = ReadKey(0); 
    $key == "\x04" and last; # Ctrl+D breaks the loop 
    print $key; 
} 

當我有它不while循環,它打印回我在打字。這個perl程序爲什麼不打印出來?

它甚至不產生結尾處的輸出(如果它是進行緩衝或東西)。就像我運行它並鍵入幾個字母並按Ctrl + D。它什麼都不打印。我是trying to make a program to convert mouse scroll escape codes into keypresses。我希望我不會咆哮錯誤的樹。

+5

使用'eq'運算符測試字符串相等性。 '=='首先將參數轉換爲數字,通常爲零。如果你把「嚴格使用」,你會被警告過。在腳本的頂部使用警告。 – amon

+0

這可能是真的,我的perl-fu確實很弱,但我幾乎肯定這不是真正的問題。 'echo「abc」| this_program'仍然不會打印任何內容。但是,如果我將循環取出並讀取並打印2個字符的「echo」abc「|」 this_program'實際上會打印出'ab' –

+1

哦,現在我明白了:你用'<>'運算符來讀取整行輸入(包括強制性的'\ n')。然後,你可以用'ReadKey(0)'來讀取一個按鍵,你可以回顯。該行(in'$ _')被丟棄。改變你的循環條件爲'while(定義(my $ key = ReadKey(0))){...}'* * really *'use strict;使用警告;'。 – amon

回答

3

此行

while (<>) 

讀取STDIN線(假設你跑不帶命令行參數的程序)。一旦一行被讀取,它就進入while循環的主體。無論你輸入和包括換行符,現在在$_

現在,您按下一個鍵,它存儲在$key中,並在數值上與CTRL-D相比較。由於既不是數字,它們最終都是零,循環終止。

這就是爲什麼你應該打開warnings它會告訴你:

Argument "^D" isn't numeric in numeric eq (==) at ./tt.pl line 15, line 1. 
Argument "c" isn't numeric in numeric eq (==) at ./tt.pl line 15, line 1.

當然,這將是有意義的把循環的終止條件屬於按照得好:

#!/usr/bin/env perl 

use strict; 
use warnings; 

use Term::ReadKey; 
ReadMode 4; 
END { 
    ReadMode 0; # Reset tty mode before exiting 
} 

my $input; 
{ 
    local $| = 1; 
    while ((my $key = ReadKey(0)) ne "\x04") { 
     print $key; 
     $input .= $key; 
    } 
} 

print "'$input'\n"; 
+0

就這樣,退出時的這段代碼會再次打印所有輸入,是嗎? –

+0

當然...顯示放入'$ input'中的內容...我假設你想用用戶按下的鍵做些什麼,對吧? –

+0

是的。我重新映射鍵和東西。我現在試圖弄清楚如何處理EOF。 'echo「abc」| myprogram | hexdump -C'顯示很多\ x00正在進入(並且不會退出)。打破循環的真正慣例是什麼?顯然,unix程序不會發送'\ x04'字節來發信號,我只接收對應於Ctrl + D的字節。 –

3

只需更換而條件:

while(1) { 
    # ... 
} 
+2

我認爲這也需要設置自動刷新'$ | = 1;'鍵盤迴顯立即發生 –