2015-10-15 217 views
-1

我将一个csh脚本移植到Perl。我在Perl中做一个switch语句。我不确定这是否正确,基于Perl中不再使用switch语句的不同意见。如果这是正确的,你可以给我一个想法吗? 同样在switch语句中,我们使用'when'还是'case'?如何将switch语句转换为Perl

这是CSH代码:

set machine = c16991 
set pgMachine = lc0140 


if (! -e /abc/site/home/$USER/.userauthentication) then 
echo "-F- .userauthentication file must be created in /abc/site/home/$USER " 
echo "-I- .userauthentication file format: <emailaddress> <unix pwd>. 
echo "-I- Please make sure /abc/site/home/$USER/.userauthentication permission is set to 000" 
exit 
endif 

set permissionCheck = `ls -ltra /abc/site/home/$USER/.userauthentication | awk '{print $1}' | 
if ($permissionCheck != 'DASHrwDASHDASHDASHDASHDASHDASHDASH') then 
echo "-F- /abc/site/home/$USER/.userauthentication permission is set to $permission1" 
exit 
endif 


@ i = 1 

while ($i <= $#argv) 
    switch ($argv[$i]) 
    case -block: 
    shift 
    set DBB1 = $argv[$i] 
    shift 
    breaksw 
    case -tag: 
    shift 
    set tag = $argv[$i] 
    shift 
    breaksw 
    case -local: 
    shift 
    set local = $argv[$i] 
    shift 
    breaksw 
    case -ar: 
    shift 
    set arType = $argv[$i] 
    shift 
    breaksw 

    default: 
    echo "-E- Invalid switch -> {$argv[$i]} found!" 
    goto usage 
    exit 
    endsw 
end 



if ($local == 'y') then 
    if ($tag == "")then 
    echo "-F- Please enter tag value to proceed!" 
    exit 
    endif 
endif 


set DBB1 = $DBB 

### grab data locally 

set shipLogFile = "$WARD/ship/log/${DBB1}.ship.log" 
set shipUsername = `grep "Username:" $shipLogFile | sed 's/.*Username: //' | sed 's/;.*//'` 
set reviewCloseFile = "$WARD/ship/ip/${DBB1}/swizzled/review/${DBB1}.close" 
set accept10SumFile = "$WARD/ship/ip/${DBB1}/swizzled/pds/logs/${DBB1}.ccdo_accept10.iss.log.sum" 
set shipDate = `zgrep "::RUNTIME:: SHIP end time/date:" $shipLogFile | sed 's/.*time\/date\://g' | sed 's#"##g'` 

else 


###grab data from archive [DEFAULT] 

if ($shipTag == "") then 
if ($DBB1 == "") then 
# grab DEFAULT hip value from running WARD, $DBB 
set DBB1 = $DBB 
endif 
# grab DEFAULT ship tag value for archive from the latest tag 
set shipTag = `ls -t $PROJ_ARCHIVE/noa/${DBB1}/ip_handoff_noa | grep "^$STEPPING" | grep RTL | grep -v RTL0 | grep -v "_TEMP" | head -n 1` 
else 
if ($DBB1 == "") then 
# grab DEFAULT hip value from running WARD, $DBB 
set DBB1 = $DBB 
endif 
endif 

set shipUsername = `zgrep "User Name:" $PROJ_ARCHIVE/noa/${DBB1}/ip_handoff_noa/$shipTag/${DBB1}.ip_handoff_noa.manifes t.gz | sed 's/.*\.//g' | sed 's/^ \+\| \+$//g'` 
set shipLogFile = "$PROJ_ARCHIVE/noa/${DBB1}/ship_noa/${shipTag}/ship/log/${DBB1}.ship.log" 
set reviewCloseFile = "$PROJ_ARCHIVE/noa/${DBB1}/iphandoff_review_noa/${shipTag}/review/${DBB1}.close. gz" 
set accept10SumFile = "$PROJ_ARCHIVE/noa/${DBB1}/ipqa_noa/${shipTag}/pds/logs/${DBB1}.ccdo_accept10.is s.log.sum.gz" 
set shipDate = `zgrep "Current Date:" $PROJ_ARCHIVE/noa/${DBB1}/ship_noa/${shipTag}/${DBB1}.ship_noa.manifest.gz | sed 's/.*\. //g'` 

endif 






### create /tmp/transpose_$$.pl script 

touch /tmp/transpose_$$.pl; rm /tmp/transpose_$$.pl 

echo '#\!/usr/intel/pkgs/perl/5.8.5/bin/perl -w' >> /tmp/transpose_$$.pl 
echo 'use strict;' >> /tmp/transpose_$$.pl 
echo 'use English;' >> /tmp/transpose_$$.pl 
echo '(our $PROG_NAME = $0) =~ s#^.*/##;' >> /tmp/transpose_$$.pl 
echo 'my $file = shift;' >> /tmp/transpose_$$.pl 
echo 'open (FILE, $file) or die "***E: Error opening $file for reading: $!\n";' >> /tmp/transpose_$$.pl 
echo 'my @lines;' >> /tmp/transpose_$$.pl 
echo 'while (<FILE>){' >> /tmp/transpose_$$.pl 
echo ' chomp $_;' >> /tmp/transpose_$$.pl 
echo ' push (@lines, $_);' >> /tmp/transpose_$$.pl 
echo '}' >> /tmp/transpose_$$.pl 
echo 'print "@lines";' >> /tmp/transpose_$$.pl 
echo 'print "\n";' >> /tmp/transpose_$$.pl 
echo '1;' >> /tmp/transpose_$$.pl 
chmod 740 /tmp/transpose_$$.pl 

这是Perl代码:

#!/usr/bin/perl 

use strict; 
use warnings; 

use Data::Dumper; ##print Dumper() 
use feature qw(switch); 

    my $machine = c16991; 
    my $pgMachine =lc0140; 


    if (! -e /abc/site/home/$USER/.userauthentication) 
    system (echo "-F- .userauthentication file must be created in /abc/site/home/$USER") 
    system (echo "-I- .userauthentication file format: <emailaddress> <unix pwd>.") 
    system (echo "-I- Please make sure /abc/site/home/$USER/.userauthentication permission is set to 000") 
    exit 
    endif 

    my $permissionCheck = `ls -ltra /nfs/site/home/$USER/.userauthentication | awk '{print $1}' 
    if ($permissionCheck != 'DASHrwDASHDASHDASHDASHDASHDASHDASH') 
    system(echo "-F- /abc/site/home/$USER/.userauthentication permission is   set to $permission1") 
    exit 
    endif 

    @ i = 1 

given ($i <= $#argv) 
switch ($argv[$i]) 
    when(block): 
    return $argv[$i] 

when(tag): 
    return $argv[$i] 

when (local): 

    return $argv[$i] 

when (ar): 
    return $argv[$i] 

default: 
    system(echo "-E- Invalid switch -> {$argv[$i]} found!") 
    goto usage 
    exit 
    endsw 
end 
+0

的'之开关功能是好的。但是有一些语法错误。 – simbabque

+0

使用[Getopt :: Long](http://p3rl.org/Getopt::Long)来处理命令行参数。 – choroba

+2

而不是'system'echo'',你可以'打印'或'说'。 – choroba

回答

1

given-when似乎试图处理命令行参数。它会工作,但根据您的需要,最好使用各种GetOpt模块之一。

GetOpt::Long为核心,并会做你想要什么:

#/usr/bin/env perl 
use strict; 
use warnings; 

use Getopt::Long; 

my %opt; 

my $DBB1; 
my $tag; 
my $local; 

GetOptions ("block=s" => \$DBB1, 
      "tag=s" => \$tag, 
      "local=s" => \$local) or die "Invalid option specified"; 

print $tag,"\n"; 

这使您可以:

myscript.pl --tag=fish 
myscript.pl --tag fish 
myscript.pl -tag fish 

并将其设置到$tag。如果您使用无效选项,它会告诉您。

我还建议你过度使用system和反引号。你不需要system ("echo ...");,但可以改为print "Something\n";。 (或使用say自动插入换行符)。

同样ls - 这有几个原因是不好的。解析ls本质上是困难的,并有一堆边缘情况,会让你起来。无论如何你都不应该那样做。

但是,特别是当您产卵ls然后awk到 - 据我所知 - 只是为了获得单个文件的权限。如果您需要扩展路径,则可以使用glob(但不这样做)。为了得到你想要的,你可以使用stat

my $perms = (stat "/nfs/site/home/$ENV{'USER'}/.userauthentication")[2] & 07777; 
if ($perms == 0600) { 
    print "Is user-rw, no access to anyone else\n"; 
} 
0

我翻译了你的脚本,为你的脚本做了什么。我不要建议饲料字段chomp -ed在另一个Perl脚本。可能有更好的方法来做你想做的事。

下面的脚本并不试图找出您希望$logFile设置为的内容。或者尝试纠正不好的处理。它只是向您展示了您尝试使用如此多的系统调用以及未经转换的csh的更好转换(不包括我的风格怪癖)。

  • -e具有引用的路径 —可以检查是否存在。
  • die是您如何退出时发生错误。
  • File::stat::stat将让你的权限
  • Getopt::Long会做所有的选项解析为您服务。
  • 你不需要为awk或grep或sed提供shell。这一切都只是方式Perl的工作原理:

而这里的代码:如果您启用

#!/usr/bin/perl 

use strict; 
use warnings; 

use File::stat; 
use Getopt::Long; 

my $user  = $ENV{USER} // 'USER NOT SET'; 
my $home_path = "/abc/site/home/$user"; 
my $auth_path = "$home_path/.userauthentication"; 
my $machine = 'c16991'; 
my $pgMachine = 'lc0140'; 

# How you error-out in Perl: just die 
die ("-F- .userauthentication file must be created in $home_path\n" 
    . "-I- .userauthentication file format: <emailaddress> <unix pwd>.\n" 
    . "-I- Please make sure $auth_path permission is set to 000\n " 
    ) 
    unless -e $auth_path 
    ; 

# stat does permissions for Perl. 
my $perms = stat($auth_path)->mode & 0777; 

if ($perms) { # non zero 
    my $permstr = sprintf "%3.3o", $perms; 
    die "-F- $auth_path permission is set to: $permstr"; 
} 

# switch processing already baked-in. 
GetOptions ('block=s' => \$DBB1 
      , 'tag=s' => \$tag 
      , 'local=s' => \$local 
      ) 
    or die "Invalid option specified" 
    ; 

die '-F- Please enter tag value to proceed!' 
    if ($local = 'y' and not $tag) 
    ; 
# $logFile is undefined in your script. 
open (my $lh, '<', $logFile) 
    or die "Could not open $logFile!" 
    ; 
open (my $out, '>', "/tmp/transpose_$$.pl") 
    or die "Could not open transpose_$$ file!" 
    ; 

# No need for grep or sed. 
while (<$lh>) { 
    #next unless s/.*Username: //; # grep + sed 
    #s/;.*//; # sed 

    # better yet, this does it all: 
    next unless my ($cap) = m/\bUsername:\s([^;]+)/; 

    # Don't do this. 
    # There should be a better way than outputing another perl script. 
    say {$out} "chomp $cap;"; 
    # Do you need to quote what you captured? 
    # say {$out} "chomp '$cap';"; 

} 
close $lh; 
+0

感谢您的评论! @Axeman,csh脚本有许多sed,awk,grep,zgrep语句。当你提到“不需要sed或grep”时,我不明白,这意味着有更好的方法来处理这种语法。该脚本还创建了一个perl脚本来创建一个新文件,以将所有csh推送到该文件,如果这可能是正确的话。有没有更好的办法呢? – luxy

+0

嗨从csh中将它移植到Perl时,“ls”的正确语法是什么?谢谢 – luxy

+0

@luxy,如果你只是想要一个目录的基名,你可以使用'glob('*')'。但我会在这里引用你:http://perlmeme.org/faqs/file_io/directory_listing.html和这里:http://search.cpan.org/perldoc?Path::Class和这里:http:// search .cpan.org /的perldoc?文件::查找::规则 – Axeman