2017-08-27 60 views
1

我正在使用IO::Selectcan_read方法來選擇準備好在簡單的perl腳本中讀取的文件句柄。Perl如何知道從IO :: Select :: - > can_read中的句柄中讀取多少個字節?

但是,文件句柄上的<...>運算符不需要傳遞給它的長度。

IO::Select到達文件句柄內部以設置「合適的長度」......或究竟發生了什麼?

#!/usr/bin/env perl 
use IO::Select; 
use strict; 
use warnings; 

my @handles = IO::Select->new(\*STDIN)->can_read(3); 

@handles == 1 or die; 

my $handle = $handles[0]; 

print ("I read " . <$handle> . "\n"); 

例如,以下腳本立即打印"a\n",然後在3秒鐘後退出。

% sh -c 'echo a; sleep 5; echo b' | perl reader.pl 
I read a 

Exit 141 

然後由於一些奇怪的原因而退出異常......不知道退出狀態是在哪裏設置的。

編輯:明顯的異常退出似乎是tcsh中的錯誤。

+0

哪個perl版本?在5.20上等待5秒鐘並正常結束。 –

+0

perl 5.24在OS X上...我懷疑退出狀態是由tcsh錯誤地報告的:/ –

+2

can_read使用select()https://metacpan.org/source/GBARR/IO-1.25/lib/IO/Select。 pm#L99 –

回答

4

IO :: Select既不知道長度,也不知道<...>運算符或readline函數知道它。相反,它只會嘗試閱讀到底有什麼內容。如果沒有找到行尾字符(即$/),它將在非阻塞文件句柄的情況下簡單地返回所有可用數據,或者在阻塞文件句柄的情況下等待行結束或數據結束。

在您的具體情況echo a; sleep 5; echo b導致線a\n和5秒後在一條線上b\n。由於您的代碼在標量環境中使用<..>,因此它只會讀取一行。這意味着它會在找到第一行結束後停止並返回此行,導致a\n

+2

此外,在同一個句柄上混合緩衝的I/O('<' '>','readline')和無緩衝的I/O('select','can_read','sysread')是一個非常糟糕的主意。 – melpomene

+0

然後用'select'和'IO :: Select'包裝選擇...我如何獲得我可以讀取的文件句柄的內容長度。我認爲'sysread'需要一個長度,因爲它是'read(2)'上的一個小包裝器。 –

+1

@GregoryNisbet:sysread中的長度參數指定__want__最多讀取多少,而不是__will__讀取多少。如果有更少的數據可用,sysread將返回這些數據(或者如果沒有數據可用,但沒有數據結束,則阻止)。 –

相關問題