Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"

Re: Filesystem and SMB/NFS share Access

by haukex (Chancellor)
on Oct 09, 2018 at 20:31 UTC ( #1223755=note: print w/replies, xml ) Need Help??

in reply to Filesystem and SMB/NFS share Access

First of all, a couple of general recommendations to improve the code:

  • Always Use strict and warnings. Although your current program only needs a few fixups, those pragmas will help you avoid typos and other mistakes.

  • Use consistent indentation. perltidy can help.

  • Reduce repetitions. I would have written something like this:

    sub exit_with_msg { my ($message,$returnid) = @_; print "CURRVALUE_STRING: $message\n"; print "RETURNID: $returnid\n"; exit 0; }

    And then used it everywhere like e.g. exit_with_msg("a File-Path must be given",1);. This will shorten your code significantly.

  • In the same vein, you seem to be assigning to $Username and $Password twice, and I'm wondering if this is correct: $Password = $opt_s;

Now, moving on to your task, note that the core Perl module File::Spec is good for cross-platform handling of filenames. For example, you can use its splitpath method to find out the volume of a path, instead of manually splitting like you are currently doing.

As for your main question, unfortunately I'm a bit rusty on my Perl+Windows+UNC. So it's a little unclear to me how you want to go about testing the files on network shares: do you want to map the shares to network drives? A quick search found several threads with information:

For example, most of these threads mention Win32::FileOp as a possibility. It's also possible to shell out to run commands like NET USE, but running external commands is usually a tricky topic, which I wrote about at length here (in this case for example, I might recommend the latest version of IPC::Run3 because it should provide for the "best" quoting of command arguments).

Replies are listed 'Best First'.
Re^2: Filesystem and SMB/NFS share Access
by PerlingAround (Novice) on Oct 10, 2018 at 07:38 UTC

    Thanks for the reply, a few things to address here.

    I wasn't my, nor my colleagues, first concern whether or not the code is short. Or effective. While I appreciate the advice for further projects it's not quite my focal point at the moment.

    The thing that is bothering me, is that since the Script is supposed to work on machines that dont quite belong to me (we are managing Servers for multiple customers) it is supposed to work "out of the box" meaning, it's supposed to work with the modules that our monitoring software delivers together with it's perl distribution which means, that it should, in general, work without further modules.

    Another restriction would be, that the colleague/person I got the task from, doesnt want the path to be mounted via a "lettered" drive. Which means they dont want something like "net use" or "pushd". Since it is not quite in my place to challenge that, it is more or less a restriction I have to live with.

    Also thanks for addressing the misslabeling of the Password assignment. I assign the option twice, because it sometime is optional and sometimes is not. Since the script, at least in the future, is also supposed to handle local filesystems and other types of shares (I think locally mounted shares wouldn't be that complicated, especially if they dont require authentication, since they would work just like local files), I basically said, that if the user is saying that I am supposed to handle an SMB share, it forces a password/username to be given, if I dont enter that conditional though, meaning, if the Filesystem given doesnt require authentication, then Password and username can be assigned but no Error will be generated if they are not given.

    As it stands, the script quite possible needs to be revised almost entirely sooner or later anyway.

      So maybe you want a better formatted and more perlish version of your script:

      use strict; use warnings; use Getopt::Std; #shift(@ARGV); my %opt=(); getopts("f:t:s:u:p:", \%opt); print "ZAXML-TXT\n"; my $Filepfad; my $Volumetype; my $Username; my $Password; my $Searchpattern; my ($opt_file, $opt_type, $opt_user, $opt_passwd, $opt_search); ($opt_file, $opt_type, $opt_user, $opt_passwd, $opt_search) = ($opt{f} +, $opt{t}, $opt{u}, $opt{p}, $opt{s}); print "$opt{f}\n"; if ($opt_file) { $Filepfad = $opt_file; } else { exit_with_msg( "A File-Path must be given", 1 ); } if ($opt_type) { if ( $opt_type ne "UNC" && $opt_type ne "local" && $opt_type ne "N +FS" && $opt_type ne "SMB" ) { exit_with_msg( "Filesystem-type must be UNC, local, NFS or SMB +", 1 ); } elsif ( $opt_type eq "SMB" ) { $Volumetype = $opt_type; if ( $opt_user && $opt_passwd ) { $Username = $opt_user; $Password = $opt_passwd; } else { exit_with_msg( "Username and Password are required for acc +ess to SMB-Shares", 1 ); } } else { $Volumetype = $opt_type; } } else { exit_with_msg( "Volumetype must be given", 1 ); } if ($opt_user) { $Username = $opt_user; } if ($opt_passwd) { $Password = $opt_passwd; } if ($opt_search) { $Searchpattern = $opt_search; } else { exit_with_msg( "A Searchpattern must be given", 1 ); } my $os = $^O; my $last_slash; if ( $os eq "MSWin32" && $Volumetype eq "local" ) { $last_slash = rindex( $Filepfad, "\\", ); } else { $last_slash = rindex( $Filepfad, "/", ); } my $Test_Volume = substr( $Filepfad, 0, $last_slash ); print "Test_Volume: $Test_Volume\n"; if ( !-d $Test_Volume ) { exit_with_msg( "Volume does not exist, isn't mounted or can't be r +ead", 2 ); } if ( -f $Filepfad ) { if ( !unlink($Filepfad) ) { exit_with_msg( "Can't delete existing File $Filepfad", 2 ); } } open my $Filehandle, '>', $Filepfad or exit_with_msg( "Can't create new file ${Filepfad} for write acc +ess", 2 ); print {$Filehandle} "Test\n" or exit_with_msg( "Couldn't write into File", 2 ); close $Filehandle or exit_with_msg( "Can't close file ${Filepfad} after writing", 2 +); open $Filehandle, '<', $Filepfad or exit_with_msg( "Can't create new file ${Filepfad} for read acce +ss", 2 ); while ( my $Content = <$Filehandle> ) { chomp $Content; if ( $Content eq $Searchpattern ) { exit_with_msg( "Files can be written and read", 3 ); } else { exit_with_msg( "File can be written but not read or file-conte +nt does not match Searchpattern", 4 ); } } #end while 1; sub exit_with_msg { my ( $message, $returnid ) = @_; print "CURRVALUE_STRING: $message\n"; print "RETURNID: $returnid\n"; exit 0; }

      I also want to mention that I personally do not like Getopt::Std, I would prefer Getopt::Long. This is a core module, so you are able to use it without installing any package from CPAN.

      Switching to Getopt::Long is left as an exercise for the OP.

      Also I included the new sub exit_with_msg inspired by haukex.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1223755]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (7)
As of 2019-12-11 09:22 GMT
Find Nodes?
    Voting Booth?

    No recent polls found