简体   繁体   中英

why is my perl system command not working?

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?

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?

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.

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.)

Check both $result and the directories themselves:

  • Make sure $result doesn't have in it (unless you're expecting subdirectories) (除非您期望有子目录)
  • Make sure $result doesn't have 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM