Perl:打开管道进行写入,但程序没有“等待”STDIN

问题描述:

我试图从一个perl脚本运行一个程序。 我将STDOUT和STDERR重定向到两个不同的文件。 我正在运行的程序要求输入一个密码,我尝试打印到进程句柄,但这不起作用,因为程序立即打印出一个验证错误,警告我我没有向STDIN写入任何内容。Perl:打开管道进行写入,但程序没有“等待”STDIN

我使用的代码与此类似:

my $s = qq(some_program > someprogram.out 2> someprogram.err); 
open(my $f, "|$s") or die "Couldn't run program: $! $?"; 
# print `cat someprogram.out`; # An error has already been printed here! 
print $f "password\n"; 
close $f or die "$!: $?"; 

我在Perl调试运行此,发现当调试运行开行,我可以运行注释掉打印线和错误已经在输出文件中。

那么,我为什么忘了这么做? 我如何判断开放“等待STDIN”?

---更新!

我没有在命令行这样的试验:

echo password | some_program 

和印刷的认证错误。所以它看起来像some_program实际上不是从STDIN读取,而是从tty读取。

有没有一种方法可以打印到tty,以便程序可以从Perl那里读取密码?

+2

你确定'some_program'是从标准输入读取密码?如果'some_program'是ssh,为了给出很多例子之一,它可能试图从终端读取,这与标准输入不一定相同。 – mob 2012-07-30 18:24:40

+0

嗨,暴徒。我不确定,但看起来是这样的。我有什么选择? – 2012-07-30 19:15:01

+0

Ssh不会和你的烟斗搭配得很好 - 使用Expect。 – 2012-07-30 21:57:17

考虑到some_program是一个bash脚本(Shell),它在其命令行上接受密码,这可以使用perl中的system调用完成。系统调用,即Perl内的程序执行不会暂停密码,最好的方法是在使用系统调用调用程序之前先询问用户密码。使用反引号执行系统调用,如下所示;

my $outfile="/path/to/someprogram.out"; 
my $errfile="/path/to/someprogram.err"; 
print "Enter password:\n"; 
$passwd=<>; 
print "some_program $passwd\n"; 
`some_program $passwd > $outfile 2> $errfile`; 

或使用system();

my $outfile="/path/to/someprogram.out"; 
my $errfile="/path/to/someprogram.err"; 
print "Enter password:\n"; 
$passwd=<>; 
my $command="some_program $passwd > $outfile 2> $errfile"; 
print "$command\n"; 
system($command);