当@array包含find命令时,为什么系统(@array)不起作用?

时间:2017-02-07 15:32:38

标签: perl

我开始喜欢Perl,但我不明白这里发生了什么。

为什么这样做

my @cmd = ();
push @cmd, 'find';
push @cmd, 'data/path/';
push @cmd, "-name";
push @cmd, '*.xml';
push @cmd, '-exec';
push @cmd, 'mv';
push @cmd, '{}';
push @cmd, 'junk/path/';
push @cmd, '\;';    
say join (' ', @cmd);       
system(join(' ', @cmd));

输出

find data/path/ -name *.xml -exec mv {} junk/path/ \;

找不到错误!虽然这不起作用

my @cmd = ();       
push @cmd, 'find';
push @cmd, 'data/path/';
push @cmd, "-name";
push @cmd, '*.xml';
push @cmd, '-exec';
push @cmd, 'mv';
push @cmd, '{}';
push @cmd, 'junk/path/';
push @cmd, '\;';    
say join (' ', @cmd);       
system(@cmd);

输出:

find data/path/ -name *.xml -exec mv {} junk/path/ \;
find: Missing argument for »-exec«.

system应该能够理解数组。见here。当我将输出复制到shell时,没有遗漏的参数,它只是起作用。但我的脚本无法执行此操作。

2 个答案:

答案 0 :(得分:11)

在第二次system来电中,您不应该逃避;

-exec切换到find会发现参数,直到找到;。 shell将;解释为命令分隔符,因此当您从命令行运行find ... -exec时,需要将其转义,并且在shell脚本中您将看到该模式

find ... -exec ... \;

在第二次system调用中,您收集数组中的所有参数并将数组直接传递给system。在这种情况下,Perl没有使用shell来解释命令,find命令看到参数\;而不是;,并且-exec开关变得混乱。

要使system命令起作用,您需要说的是

...
push @cmd, ';';
...
system(@cmd);

答案 1 :(得分:5)

mob pointed outnull电话的直接问题,但有更好的方法可以做到这一点。您可以使用File::Find::Rule而不是执行外部命令,See it live on Coliru的接口与system实用程序非常相似:

find