perl - 在 Perl 脚本中,我们应该使用 shell 命令还是调用模仿 shell 操作的 Perl 函数?

标签 perl shell

我想了解这里的最佳实践。假设我想获取文件某行的内容。我可以使用一行shell命令来得到我的答案,或者编写一个子程序,如下面的代码所示。

一个名为 some_text 的文本文件:

She laughed. Then both continued eating in silence, like strangers,
but after dinner they walked side by side; and there sprang up
between them the light jesting conversation of people who are free
and satisfied, to whom it does not matter where they go or what
they talk about.

获取文件第 5 行内容的代码
#!perl
use warnings;
use strict;

my $file = "some_text";
my $lnum = 5;
my $shellcmd = "awk 'NR==$lnum' $file";
print qx($shellcmd);
print getSrcLine($file, $lnum);

sub getSrcLine {
    my($file, $lnum) = @_;
    open FILE, $file or die "$!";
    my @ray = <FILE>;
    return $ray[$lnum-1];
}

我问这个是因为我看到很多 Perl 脚本在某些时候调用了一个 shell 命令,而在稍后的某个时候,通过调用(库或手写)函数来完成相同的任务,例如,rm -rfFile::Path::rmtree 。我只是想让它保持一致。

建议做什么?

最佳答案

如果有用于操作的 Perl 函数,Perl 认为您应该使用它的版本。但是,您给出了一个 Perl 模块的示例,该模块提供了一种纯 Perl 方式来执行此操作。那是很不一样的。没有单一的答案(就像大多数事情一样),所以你必须自己决定要做什么:

  • 纯 Perl 方法是否正确执行?例如,File::Copy有一些限制,因为它为用户做出了一些尴尬的决定,所以很多人认为它已经坏了。例如,参见 File::Copy versus cp/mv .
  • 纯 Perl 方法是否在可接受的时间内完成?有时,外部程序的速度要快几个数量级。有时它会慢很多。
  • 外部命令通常可以在一个系统家族(例如所有类似 linux 的系统)内移植,但可能不能跨家族移植(例如 Windows 和 linux)。您对此的容忍度可能会影响您的答案。即使您认为您正在运行相同的命令,不同风格的类 unix 系统也可能有不同的操作开关。
  • 将复杂的参数(空格、引号和特殊字符)传递给外部命令会让你哭泣。您必须做很多繁琐的工作才能确保正确处理参数。 Perl 子例程并不关心。
  • 当您使用外部命令时,您必须更加注意自己在做什么。如果您只是调用rm , Perl 会搜索你的 PATH并使用名为 rm 的第一件事.这并不意味着它是您认为的程序。我在 Mastering Perl 的“安全编程技术”中写了很多关于这个的内容。
  • 如果纯粹的 Perl 方法需要一个模块,特别是如果该模块有许多复杂的依赖关系,那么你可能会在 future 陷入依赖关系或分发 hell 。

  • 就个人而言,我从纯粹的 Perl 方法开始,直到它不适用于这种情况。

    对于您的特定示例,我将使用 Perl。对 awk 进行炮击,这是一个原始 Perl,这很奇怪。你应该能够做所有 awk 做对 Perl 的事情。如果你有一个 awk 程序,你可以用 a2p 程序把它转换成 Perl:
     NR==5
    

    a2p 将其转换为(以开始时的一些设置位为模):
    while (<>) {
        print $_ if $. == 5;
    }
    

    请注意,即使您有第五行,它仍会扫描整个文件。但是,您可以使用翻译后的程序作为开始:
    while (<>) {
        if( $. == 5 ) {
            print;
            last;
            }
    }
    

    我认为您不应该使用其他程序来避免该 Perl 代码。

    要删除目录树,我喜欢 File::Path .它有一些依赖关系,但它们都在 Perl 标准库中。如果有的话,与该模块相关的痛苦很小。我会一直使用它,直到遇到它不起作用的问题。

    关于perl - 在 Perl 脚本中,我们应该使用 shell 命令还是调用模仿 shell 操作的 Perl 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9967063/

    相关文章:

    python - 如何使用 python 脚本运行远程 shell 命令

    perl - 为什么 system() 即使它执行的程序死了也返回 0

    mysql - Perl DBI 执行不维护 MySQL 存储过程结果

    mysql - while 循环只存储来自 @row=$sth->fetchrow_array() perl 的一个值

    bash - 如何为 Emacs mingw32 for Windows 运行 Windows 10 的 bash?

    linux - .gitlab-ci.yml 中最简洁明了的SSH命令描述方式

    perl - 如何使用 Perl MongoDB 包在 Mongo 副本上进行 MapReduce

    perl - 我如何使用 Perl 的 WWW::Facebook::API 发布到用户的新闻源?

    linux - 为什么我在数字比较时收到命令未找到错误?

    shell - shell 中的 let vs expr vs 双括号算术