2013-01-15 51 views
1

这是我的Perl代码将结果移动到发送的文件夹。为什么我的perl系统命令不起作用?

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

我得到的错误是:

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

我到底错在这里做什么?

回答

4

这很难说,但有几件事情可以帮助你解决问题。

首先确保你的脚本开始这样的:

#!/pathe/to/perl -w 

use strict; 

通知的-w启用警告。另外use strict将帮助您识别代码问题。

另一件事,帮助了很多的存储要在一个标量运行的命令,并打印出来,看看它究竟是干什么:

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

在你的脚本,你得到$结果来自用户输入?我有一种感觉,它有一个换行符。 chomp函数将安全地从字符串末尾删除换行符。

+0

这让我在正确的轨道上。谢谢!我最终需要$ result =〜s/\ n // g; – BluGeni

+0

@BluGeni呃,糟糕的\ n'符号,讨厌它在行末:\ – gaussblurinc

+0

请注意,使用这段代码你永远不会知道你的'mv'命令是否因任何原因失败 - 比如缺少权限,错误的文件名等... – mvp

7

最有可能的$result包含一个换行符,它会过早地终止该命令。使用chomp放弃额外的换行符。

如果$result来自用户输入,并且没有被裁切,那么几乎肯定会有一个换行符。而且,根据您程序的受众,您现在有恶意代码注入问题。

为了避免注入问题,如何使用rename函数将文件移动到目的地?

1

检查两个$result和目录本身:

  • 确保$result没有斜杠在它(除非你希望子目录)
  • 确保$result没有空格因为该命令不使用引号
  • 请确保$result不为空

对于目录:

  • 确保/home/pi/downloads存在且是一个目录
  • 确保/home/pi/downloads/sent存在且是一个目录
  • 确保/home/pi/downloads具有写权限
  • 确保/home/pi/downloads/sent拥有可写权限

3

虽然你可以调用外部程序到您使用system()qx{}的做一些事情,Perl是非常强大和灵活,并为许多常见的操作就可以做到用刚刚Perl本身(或它的许多模块),无使用任何外部。如果出现任何外部程序问题,它会更快更可靠。例如,如果外部可执行文件有问题并且处于紧密循环中,则system()可能永远不会返回,从而冻结您的脚本。

在你的情况,这Perl代码更好地工作和处理错误:

use File::Copy; 

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

(当然,你应该确保$result不包含换行符运行此之前。)

+0

谢谢你,我会用这个代替我的代码。 – BluGeni

+0

然后确保接受您实际使用的解决方案。 – mvp

相关问题