Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

Re: Check if file exists in multiple directories

by FreeBeerReekingMonk (Deacon)
on May 21, 2015 at 18:45 UTC ( [id://1127381]=note: print w/replies, xml ) Need Help??


in reply to Check if file exists in multiple directories

Change this:

system("mv $out $newdir");

To this:

$errormessage = `/bin/mv "$out" "$newdir" 2>&1`; if($?){ warn "Error($?) There was a problem " . "copying '$out' to '$newdir': $! \n $errormessage\n"; }

Replies are listed 'Best First'.
Re^2: Check if file exists in multiple directories
by afoken (Chancellor) on May 22, 2015 at 07:13 UTC

    Change this:

    system("mv $out $newdir");

    To this:

    $out = `/bin/mv "$out" "$newdir" 2>&1`;

    Please DON'T!

    Don't mess with the shell at all. You simply can't write robust code that way. Shells behave far too different on different systems.

    (Apart from that, this code breaks when $out or $newdir contains double quotes. Yes, those characters are legal in filenames. Only NUL (chr(0)) and / are not allowed. This code also breaks when $out or $newdir contains $, due to the double quotes passed to the shell. Single quotes would have prevented that, but then filenames better don't contain single quotes.)

    Better ways, ordered from worst to best:

    1. Invoke /bin/mv via Safe Pipe Opens, using open(HANDLE,'-|') and exec('/bin/mv',$out,$newdir) as documented. This avoids all shell issues, but still lacks a sane error reporting. /bin/mv writes to STDERR, perhaps also to STDOUT, and that output depends very much on the system and the system settings. Both rename() and File::Copy::move() below report errors by returning a false value, the actual error is stored in $!, no matter how the system is configured.
      You need about 20 lines of code for this, most copied from perlipc.
    2. Simply use Perl's rename function. Note that rename() may fail when crossing filesystem boundaries. So you may need to add some fallback code for that case IF source and destination directory may be on different filesystems. Also note that the second argument often has to be a filename if the first argument is a filename, i.e. you can't rename a file to a directory. So you may need to extract the name part from the first argument and append it to the second argument.
      One line of code for the trivial case, about 10 lines of code for handling rename($file,$directory) correctly, about 200 lines of code (see source of File::Copy) for fallback code and OS specific issues. Falback code may be much shorter (about 20 lines of code) if you write for only a single OS, omit many sanity checks, and ignore many special cases and file permissions.
    3. Use the File::Copy module. It provides a move() function (also available as mv()) that actually behaves very much like /bin/mv: It can rename even across filesystem boundaries and allows move($file,$directory). Actually, move() IS just rename() plus the fallback code and filename handling code that you would need to write. File::Copy also knows the required OS specific workarounds. File::Copy is part of the perl core distribution, i.e. it is installed with perl and thus available without extra steps.
      Two line of code for all cases, all operating systems:
      use File::Copy qw( move ); move($source,$destination) or die "Can't move '$source' to '$destinati +on': $!";

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
      Ahh... passionate, perfect error-free 'not throw away' code. Rich, meaningful explanation. You have my vote, sir.
      die "Punct filename is bad, mmkay" if $file =~ m{\p{Punct}} ;

        :-)

        But tell that those nasty users that name files like "Pictures - from 2006 (or was it 2007), but not those nasty ones. (Only those for presentation at the big teather in London or Sidnee [or how to those cangaroo ridders call there capital].) For the grinding halt project only! Don't use elsewhere!!! §§§§§§§TOPSECRIT§§§§§§§§§.doc". And better don't ask for the directory names.

        (No, I don't invent that, I've seen file paths so long that Windows refused to work with them, including spelling errors like those above. From people getting paid more per month than some families get in a whole year.)

        Alexander

        --
        Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (6)
As of 2024-04-23 18:51 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found