我创造了重现问题的条件,但一切都很顺利:
来电者.pl:
#! /usr/bin/perl
$cmd = "echo 'a\\
b\\
c\\
d\\
e\\
f' | ~/doc/Answers/src/pltest/cmd1.csh";
sub system_tcsh
{
@args = ("tcsh", "-c", $cmd);
return system(@args);
}
system_tcsh
cmd1.csh:
#! /bin/csh
echo "${0}(cmd1) $argv[*]"
set line1 = $<
set line2 = $<
set line3 = $<
setenv lineno 3
echo "cmd1: read: $line1 $line2 $line3"
./cmd2.csh
cmd2.csh:
#! /bin/csh
echo " ${0}(cmd2) $argv[*] now running..."
./cmd3.csh
./cmd3.csh
set line6 = $<
echo " ${0}: Read: $line6"
cmd3.csh:
#! /bin/csh
# cmd3
set line = $<
echo " ${0}: Read: '$line'"
试运行:
frayser@gentoo ~/doc/Answers/src/pltest $ ./caller.pl
/export/home/frayser/doc/Answers/src/pltest/cmd1.csh(cmd1)
cmd1: read: a b c
./cmd2.csh(cmd2) now running...
./cmd3.csh: Read: 'd'
./cmd3.csh: Read: 'e'
./cmd2.csh: Read: f
也许你可以修改它来重现问题,或者用它来实现你的解决方案。
--
更新
这是一个重现 Perl STDIN 问题的更新,并提供了解决方法。
用 Perl 版本替换 cmd3 会给出报告的有问题的结果:
替换 cmd3.csh 的 cmd3.pl:
#! /usr/bin/perl
# cmd3
$_=<STDIN>;
chomp();
print " $0: Read: '$_'\n";
结果:使用cmd3.pl。读取“d”后,没有更多输入可用。
./caller.pl
./cmd1.csh(cmd1)
cmd1: read: a b c
./cmd2.csh(cmd2) now running...
./cmd3.pl: Read: 'd'
./cmd3.pl: Read: ''
./cmd2.csh: Read:
为了纠正这种情况,将cmd2更改为仅向cmd3发送 1 行。第(1)行命令很容易做到这一点:
#! /bin/csh
echo " ${0}(cmd2) $argv[*] now running..."
line | ./cmd3.pl
line | ./cmd3.pl
set line6 = $<
echo " ${0}: Read: $line6"
这是cmd2.csh优化以避免执行line命令的开销。
#! /bin/csh
echo " ${0}(cmd2) $argv[*] now running..."
set x = $<
echo $x | ./cmd3.pl
set y = $<
echo $y | ./cmd3.pl
set line6 = $<
echo " ${0}: Read: $line6"
这是更新后的cmd2.csh的输出。现在使用Perl的功能与使用csh 作为最终脚本的功能相同:不会丢失标准输入。
./cmd1.csh(cmd1)
cmd1: read: a b c
./cmd2.csh(cmd2) now running...
./cmd3.pl: Read: 'd'
./cmd3.pl: Read: 'e'
./cmd2.csh: Read: f