2015-10-15 233 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