2012-01-27 77 views
2

我想从默认输入中读取数据是否传入或提供了文件,但如果没有提供,我想提供默认值while(<>)来执行。基于命令行参数的Perl设置文件句柄

伪代码:

if(!<>){ 
    <> = system("ls | ./example.pl"); 
} 

while(<>){ 
... 
... 
... 
} 
+0

你实施的哪一部分让你失望? – 2012-01-27 01:26:12

+0

这似乎不是有效的。我想设置<>。此外,测试('if(!<>)')似乎不正确。 – Chris 2012-01-27 01:27:09

+0

@Chris的权利,没有一个是真的明智的。 '<>'是从文件读取的运算符。你不能设置它,并且执行'if(!<>)'从某处读取一行并测试*那行*是真还是假。 – hobbs 2012-01-27 01:32:22

回答

5

你 “如果数据是在管道” 刁难。这很容易说

if ([email protected]) { 
    @ARGV = ("somedefault"); 
} 

while (<>) { 
    ... 
} 

,如果没有文件名在命令行给出的,这将在“somedefault”工作 - 但这意味着你永远不会从标准输入读取Perl的默认值,如果没有任何文件名上命令行。

一种可能的妥协是使用-t operator猜测标准输入是否是终端:

if ([email protected] && -t STDIN) { 
    @ARGV = ("somedefault"); 
} 

如果没有在命令行标准输入连接到终端的文件名将使用“somedefault” ,但如果没有文件名并且stdin从文件或管道重定向,它将使用stdin。这有点神奇(可能令人讨厌),但是按你的要求。

+0

当我尝试用'system(“ls”)替换'(某些默认值)'时,终端将永远运行。我把它弄错了吗?我也尝试过“ls | ./ctime”,但似乎无限递归。 – Chris 2012-01-27 03:37:17

+1

这些都没有意义。 ''ls |“'也许有道理。 – hobbs 2012-01-27 03:56:01

4

如何尝试从<>中读取,然后在没有读取任何内容时回到默认值?

while (my $line = <>) 
{ 
    do_stuff($line); 
} 

# if no lines were read, fall back to default data source 
if (not $.) 
{ 
    while (my $line = <SOMETHING_ELSE>) 
    { 
      do_stuff($line); 
    } 
} 

您可以阅读有关$.变量here, at perldoc perlop - 它表示最近的文件句柄读取的“当前”的行号。如果未定义,则从<>没有任何可读的内容。