【问题标题】:executing a bash script in perl在 perl 中执行 bash 脚本
【发布时间】:2012-08-20 19:27:15
【问题描述】:

我想在 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");

但不起作用。

【问题讨论】:

  • 该 shell 代码很容易在 Perl 中实现。除非必要,否则涉及几种不同的语言是错误的

标签: perl bash


【解决方案1】:

使用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";
    }
}

【讨论】:

  • 非常感谢,但重点是我想在我的 Perl 程序中使用 shell script 命令:)
【解决方案2】:

您的报价已关闭。

"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 为您提供了广泛的可能性。这些引用语法 interpolate 变量在:"…" 和 qq{…} 中,您可以使用 [^\s\w] 中的任何字符作为分隔符,non-interpolating 语法是:@987654327 @ 和 q{…} 具有与以前相同的分隔符灵活性:

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

q 和 qq 构造可以在字符串中包含分隔符,如果出现是平衡的: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

这对于包含更长的片段而不用担心分隔符很有用。字符串以预定义的标记结束,该标记必须单独出现在一行中。如果分隔符声明放在单引号中(&lt;&lt;'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 中的字符作为分隔符。您必须在引用运算符q 或qq 和分隔符之间包含一个空格。这有效:q xabcx 等于 'abc'。

【讨论】:

  • 我删除了 $ ,而不是你提到的“”我使用了 qq,仍然抱怨
  • @shaq 哪一部分不起作用?您是否在 Perl 中收到 语法错误,或者它在运行时失败还是 shell 脚本失败?错误信息说什么?最后一个代码片段我编译好了。
【解决方案3】:

尝试启动一个运行脚本的 bash 实例,而不是启动脚本。例如

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

【讨论】:

  • 我希望脚本在我的 Perl 程序中
  • @shaq: 这是一个 Perl 解决方案
  • 对不起,我在想你的意思是我必须将我的脚本名称传递给 bash ,无论如何,我做了你说的它仍然在抱怨
【解决方案4】:

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

【讨论】:

    猜你喜欢
    • 2013-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多