Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I am trying to write something in Perl where it works like the Unix mv command where it is given command line arguments.

Is this the right direction??? It doesnt seem to work for me.
$ARGV[0] = $h; $ARGV[1] = $b; system("mv $h $b");

Replies are listed 'Best First'.
Re: Unix command working with Perl
by particle (Vicar) on May 31, 2002 at 13:41 UTC
    check out the docs for system. use the multiple argument form, and check the return code. also, use taint mode to check the arguments for nasty surprises. the following code is untested...

    Update: note this code applies to any system calls, not just 'mv'. there are better tools for moving files, as mentioned by other monks.

    #!/usr/bin/perl -wT use strict; ## check your arguments @_ == 2 or die "Usage: $0 from to\n"; ## specify your command my $cmd = '/usr/bin/mv'; ## untaint your input my( $from ) = ( $ARGV[0] =~ s/(\w|[/\\])+/$1/ ); my( $to ) = ( $ARGV[1] =~ s/(\w|[/\\])+/$1/ ); ## make sure the input is good ( defined $from and defined $to ) or die "ERROR: $0 - bad input\n"; ## run the command without using the shell ## check return code for errors system( $cmd, $from, $to ) or die "ERROR: $0 - can't $cmd! $!";
    Update: escaped backslash in regex

    ~Particle *accelerates*

      thanks for all the answers! I keep getting the following errors:
      /(\w|[/: unmatched [] in regexp at tes2 line 12.
      The other error keeps popping up reference to checking of arguments but I am running it with two arguments at command line. My script name is tes2:
      tes2 Oldfile Newfile
      Usage: tes2 from to

        Update: Ahh, this was a comment to particle's code ... now I see ... nothing to see here

        /(\w|[/: unmatched [] in regexp at tes2 line 12.
        Aehmm, what regex?? If you show us all your code we might be able to help you ...

        -- Hofmator

        the \ should have been escaped... i didn't think that was necessary in brackets. i've updated my code.

        ~Particle *accelerates*

Re: Unix command working with Perl
by talexb (Chancellor) on May 31, 2002 at 13:35 UTC
    Is there any reason why you can't use rename? You should be able to use that for moving files.

    --t. alex

    "Nyahhh (munch, munch) What's up, Doc?" --Bugs Bunny

      I would generally recommend the usage of the move method of File::Copy over that of the internal perlfunc:rename function. This is due to the limitations of the internal perlfunc:rename function with regard to copying across file systems and other platform specific anomalies such as the handling of open files - This is documented in both the perlfunc:rename and perlport man page.

       

      Is there any reason why you can't use rename?

      Moving files across filesystem boundaries? It doesn't work with rename.

      I always use File::Copy instead of rename for this reason.

      use File::Copy; move('/old/path', '/new/path') or die "Can't move: $!";

      --
      Ilya Martynov (http://martynov.org/)

Re: Unix command working with Perl
by broquaint (Abbot) on May 31, 2002 at 13:42 UTC
    If this is the entirety of your script then the reason it won't work is that you're assigning to @ARGV instead of from it, so $h and $b will be undefined. However if this is just a snippet then ...

    Are you sure mv is in the PATH? Also you'll want to quote $h and $b to protect against spaces if you want to use command-line programs. Probably a better option is to use File::Copy as it can run anywhere perl can and is a core module e.g

    use File::Copy; move($ARGV[0], $ARGV[1]);
    Another thing to be weary of is $b as it is a special variable associated with sort().
    HTH

    _________
    broquaint

Re: Unix command working with Perl
by Albannach (Monsignor) on May 31, 2002 at 13:41 UTC
    Well you have a bit of a thinko there, in that you are assigning your undefined variables to overwrite your argument list, when you should be doing it the other way around (use strict and warnings or -w would help you a lot). A better option would be to use File::Copy. rename is often ok but a bit unpredictable as to what capabilities it has depending on your OS.

    --
    I'd like to be able to assign to an luser

Re: Unix command working with Perl
by Steve_p (Priest) on May 31, 2002 at 13:57 UTC
    I'd suggest using the File::Copy module. The following code should show you how its used.
    #!/usr/bin/perl -w use strict; use File::Copy; move("fromfile","tofile") or die "Unable to move: $!";
Re: Unix command working with Perl
by Hofmator (Curate) on May 31, 2002 at 13:44 UTC
    shouldn't that read
    $h = $ARGV[0]; $b = $ARGV[1]; system("mv $h $b");

    You want to assign from $ARGV[0] to $h and not the other way round.

    Apart from that I would suggest using File::Copy as your solution only works if you actually are on Unix:

    use File::Copy; move($ARGV[0], $ARGV[1]);

    Update: :(( typed too slow, a couple of other monks beat me to it ...

    -- Hofmator