在perl中执行bash脚本

时间:2012-08-20 10:53:22

标签: perl bash

我想在perl中运行此命令

for dir in *; do
 test -d "$dir" && ( find "$dir" -name '*test' | grep -q . || echo "$dir" );
 done

我试过了:

 system ("for dir in *; do
        test -d "\$dir" && ( find "\$dir" -name '*test' | grep -q . || echo "\$dir" );
        done");

但不起作用。

4 个答案:

答案 0 :(得分:3)

使用File::Find模块的find函数的纯Perl实现:

#!/usr/bin/env perl

use strict;
use warnings;

use File::Find;

find \&find_directories, '.';

sub find_directories {
    if ( -d && $File::Find::name =~ /test$/ ) {
        print "$File::Find::name\n";
    }
}

答案 1 :(得分:1)

您的报价已关闭。

"for dir in *; do
    test -d "\$dir" && ( find "\$dir" -name '*test' | grep -q . || echo "\$dir" );
    done"

您已决定使用双引号"分隔字符串,但它们包含在您的字符串中。

转义其他引号

"for dir in *; do
    test -d \"\$dir\" && ( find \"\$dir\" -name '*test' | grep -q . || echo \"\$dir\" );
    done"

(容易出错,丑陋)

...或使用其他分隔符:Perl为您提供了广泛的可能性。这些引用语法插入变量内部:"…"qq{…},您可以使用[^\s\w]中的任何字符作为分隔符,非插值语法为:'…'q{…},具有与以前相同的分隔符灵活性:

qq{for dir in *; do
    test -d "\$dir" && ( find "\$dir" -name '*test' | grep -q . || echo "\$dir" );
    done}

qqq构造可以在字符串中包含分隔符,如果事件是平衡的:q( a ( b ) c )有效。

第三个引用机制是 here-doc

system( <<END_OF_BASH_SCRIPT );
for dir in *; do
    test -d "\$dir" && ( find "\$dir" -name '*test' | grep -q . || echo "\$dir" );
    done
END_OF_BASH_SCRIPT

这对于包含更长的片段而不用担心分隔符很有用。 String由预定义的标记结束,该标记必须出现在它自己的一行上。如果分隔符声明放在单引号(<<'END_OF_SCRIPT')中,则不会插入任何变量:

system( <<'END_OF_BASH_SCRIPT' );
for dir in *; do
    test -d "$dir" && ( find "$dir" -name '*test' | grep -q . || echo "$dir" );
    done
END_OF_BASH_SCRIPT

关于q{}qq{}语法的注意事项:这是一个永远不会在混淆之外使用的功能,但可以使用\w中的字符作为分隔符。您必须在引用运算符qqq与分隔符之间包含空格。这有效:q xabcx并且等于'abc'

答案 2 :(得分:0)

尝试启动运行脚本的bash实例,而不是启动脚本。 E.g。

system("bash -c 'for dir bla bla bla'");

答案 3 :(得分:0)

system()使用您的默认系统shell,可能不是Bash。解决方案是call Bash explicitly with the system() command