我目前正在将一些脚本从csh翻译为perl。我遇到过一个具有以下开关控制的脚本
#And now some control
set get_command = h
set finish = 0
while (1)
switch ($get_command)
case "h":
case "H":
set cine_command = ""
cat << EOF
Control synchronised cine by (case insensitive):
A - A view data
B - B view data
a - accelerate
d - decelerate
r - real time heart rate
<num> - rate (frames per second)
i - toggle interpolation
s - step through (may lose a little synchronisation)
c - continue (restart) after stepping
y - reverse direction
h - help (repeat this)
f - finish (quit)
q - quit (finish)
<return> - quit
EOF
breaksw
case "":
case "f":
case "F":
case "q":
case "Q":
set cine_command = '-f'
set finish = 1
breaksw
case "a":
set cine_command = '-a'
breaksw
case "d":
case "D":
set cine_command = '-d'
breaksw
case "r":
case "R":
set cine_command = "-t $time_per_frame"
breaksw
case "i":
case "I":
set cine_command = '-i'
breaksw
case "s":
case "S":
set cine_command = "-s"
breaksw
case "c":
case "C":
set cine_command = "-c"
breaksw
case "y":
case "Y":
set cine_command = "-y"
breaksw
case '[0-9]*':
set cine_command = "-r $get_command"
breaksw
default:
echo "$get_command ignored"
set cine_command = ""
endsw
if ('$cine_command' != '') then
select_tv $FIRST_TV
cine $cine_command
select_tv $SECOND_TV
cine $cine_command
endif
#
# If we're stopping then get out of this loop.
#
if ($finish) break
echo -n "cine > "
set get_command = $<
end
我在我的系统上安装了Perl 5.8.8并使用use Strict;
我知道在下一个perl版本中可能会被弃用,我尝试了以下
#Add some fine control to script
my $get_command = 'h';
my $finish = 0;
my $cine_command;
while(<>)
{
switch ($get_command)
{
case [hH] {$cine_command = "";}
print STDOUT << 'END';
Control synchronised cine by (case insensitive):
A - A view data
B - B view data
a - accelerate
d - decelerate
r - real time heart rate
<num> - rate (frames per second)
i - toggle interpolation
s - step through (may lose a little synchronisation)
c - continue (restart) after stepping
y - reverse direction
h - help (repeat this)
f - finish (quit)
q - quit (finish)
<return> - quit
END
case [fFqQ]
{
$cine_command = '-f';
$finish = 1;
}
case "a"
{
$cine_command = '-a';
}
case [dD]
{
$cine_command = '-d';
}
case [rR]
{
$cine_command = "-t $time_per_frame";
}
case [iI]
{
$cine_command = '-i';
}
case [sS]
{
$cine_command = '-s';
}
case [cC]
{
$cine_command = '-c';
}
case [yY]
{
$cine_command = '-y'
}
case /\d/
{
$cine_command = "-r $get_command";
}
else
{
print "$get_command ignored\n";
$cine_command = "";
}
if ($cine_command ne "")
{
`select_tv $FIRST_TV`;
`cine $cine_command`;
`select_tv $SECOND_TV`;
`cine $cine_command`;
}
exit if( $finish == 1);
print STDOUT "cine > \n";
chomp(my $get_command = <STDIN>);
}
}
当我按下返回时,我会在终端上打印所需的选项。但是,当我在STDIN中键入任何选项时 - 例如a,h或d - 我没有得到任何响应。当我输入retirn时 - 我按预期将“h ignored”消息打印到终端。
有什么想法吗?
答案 0 :(得分:2)
对于那些说获取更新版Perl的人:并非所有人都能控制他们的系统。如果OP在Red Hat上,它可能是公司机器,这意味着OP无法控制它。 Perhat在Redhat上的最新版本是5.8.8。我们可能认为它古老而且过时,但Perl的许多公司版本都使用它。
我在我控制的本地计算机上拥有最新和最好的Perl版本,但我必须使用Perl 5.8.8语法编写,我必须假设我无法下载任何CPAN模块。
这是现实生活,它可以吸吮。但是,你必须忍受它......
首先,Perl和Csh是两种完全语言,并且将任何语言逐行翻译成另一种语言并不是一个好主意。 Perl是一种功能更强大的语言,使用许多功能来改进你的csh脚本可能会很好。
如果要解析命令行,请查看使用模块Getopts::Long,它将为您完成大量工作,并在Perl 5.8.8中提供。这可能与您尝试使用switch语句完全相同,并且工作量更少,而且更灵活。
我会避免在Perl中使用switch
语句。它从来没有真正起作用。新的given/when
内容效果更好,但唉,它仅在Perl 5.10之后才可用。
相反,忘记切换内容并使用if/elsif
结构然后case语句:
my $usage =<<USAGE;
Control synchronised cine by (case insensitive):
A - A view data
B - B view data
a - accelerate
d - decelerate
r - real time heart rate
<num> - rate (frames per second)
i - toggle interpolation
s - step through (may lose a little synchronisation)
c - continue (restart) after stepping
y - reverse direction
h - help (repeat this)
f - finish (quit)
q - quit (finish)
<return> - quit
USAGE
$cine_command;
$finish;
while ( my $command = get_command() ) {
if ( $command =~ /^h$/i ) {
print "$usage\n";
exit 0;
}
elsif ( $command =~ /^(fq)$/i ) {
$cine_command = '-f'
$finish = 1
}
elsif ( $command =~ /^a$/i ) {
$cine_command = '-a';
}
elsif ...
它不如 switch 语句那么优雅,但它可以完成工作并且易于理解和维护。还可以利用正则表达式匹配。例如,$command =~ /^(fq)$/i is checking to see if
$ command is equal to
F ,
f ,
q , or
Q`同时出现。
答案 1 :(得分:0)
while(<>){}
与csh中的while(1)
不等效。 perl中的while(<>)
相当于while(defined($_ = <>))
,这是一个读取和检查,看到还没有达到eof。尝试将while(<>)
替换为while(1)
。
答案 2 :(得分:0)
对于包含大量选项的大型程序,您可能会查看App::Cmd之类的内容。否则,subrefs的散列可能适用于委托而不是switch语句。