为什么系统调用会影响perl中的后续打印行为?

时间:2013-03-15 06:37:49

标签: perl buffer system-calls tcsh

这是我的代码

#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;

my $file = $ARGV[0];
system('wc -l $file');
print "\nprinting alpha \n";
sleep 1;
exit;

运行后(在tcsh shell中)perl script.pl /path/to/file我没有看到printing alpha,直到我按Ctrl+C。即使我在系统调用之前或之后添加另一个语句$|=1,行为仍然是相同的。

发生了什么事?

2 个答案:

答案 0 :(得分:4)

您正在执行shell命令

wc -l $file

shell没有定义变量$file,因此与

相同
wc -l

这会导致shell使用单独的arg wc执行-l。如果没有提供文件名,wc将从STDIN读取,直到您使用Ctrl-C中的SIGINT将其终止。


你可能正在瞄准

system("wc -l $file");   # XXX

但那也错了。这不会将参数-l$file的值传递给wc。考虑如果提供了带有空格的文件名会发生什么。

要构建一个导致文件名正确的shell文字,可以使用

use String::ShellQuote qw( shell_quote );
system(shell_quote('wc', '-l', $file));

但更好的选择是避免shell并直接执行wc,将所需的值传递给它而不必构建shell命令。

system('wc', '-l', $file);

答案 1 :(得分:1)

因为单引号会阻止$file的插值。改为双引号。

正在执行的是正在执行字符串而不替换$file的值。当shell获取它时,它会查找一个不存在的shell变量$file,因此它执行没有文件的命令。这会导致wc从stdin读取,从而导致您看到的行为。