1

This is my perl code to move result to the sent folder.

 system("mv /home/pi/downloads/$result /home/pi/downloads/sent/$result");

The error i get is:

mv: missing destination file operand after `/home/pi/downloads/filename.txt'

What am i doing wrong here?

4 Answers 4

8

Most likely $result contains a newline, which prematurely terminates the command. Use chomp to discard the extra newline.

If $result comes from user input and it wasn't chomped, there's almost certainly a newline character. And, depending on the audience for your program, you now have a malicious code injection problem.

To avoid the injection problem, how about using the rename function to move the file into the destination?

Sign up to request clarification or add additional context in comments.

Comments

5

That's difficult to say but there's a few things you can do that should help you solve it.

First make sure your script starts like this:

#!/pathe/to/perl -w

use strict;

Notice the -w to enable warnings. Also use strict will help you identify code issues.

Another thing that helps a lot is storing the command you want to run in a scalar and printing it to see what it is actually doing:

my $result = "filename.txt";
chomp($result);
my $cmd = sprintf("mv /home/pi/downloads/%s /home/pi/downloads/sent/%s", $result, $result);
print "$cmd\n";
system($cmd);

In your script do you get the value for $result from user input? I have a feeling it has a newline character. The chomp function will safely remove newline characters from the end of a string.

3 Comments

this got me on the right track. thanks! I ended up needing $result =~ s/\n//g;
@BluGeni uh, bad \n symbol, hate it at the end of line :\
Note that using this code you will never know if your mv command has failed for any reason - like lack of permissions, wrong filename, etc...
3

While you can call external programs to do something for you using system() or qx{}, Perl is extremely powerful and versatile, and for many common operations it can be done using just Perl itself (or its numerous modules), without using anything external. It is both faster and more reliable if any problems with external programs arise. For example, if external executable is buggy and spins in tight loop, system() may never return, freezing your script.

In your case, this Perl code works better AND handles errors:

use File::Copy;

unless (move ("/home/pi/downloads/$result",
              "/home/pi/downloads/sent/$result"))
{
    print "Rename has failed!\n";
    # ...
}

(Of course, you should make sure that $result does not contain newlines before you run this.)

Comments

1

Check both $result and the directories themselves:

  • Make sure $result doesn't have slashes in it (unless you're expecting subdirectories)
  • Make sure $result doesn't have spaces in it since the command doesn't use quoting
  • Make sure $result isn't empty

For the directories:

  • Make sure /home/pi/downloads exists and is a directory
  • Make sure /home/pi/downloads/sent exists and is a directory
  • Make sure /home/pi/downloads has writable permissions
  • Make sure /home/pi/downloads/sent has writable permissions

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.