【问题标题】:system("linux_command") vs. Perl library functionssystem("linux_command") vs. Perl 库函数
【发布时间】:2013-11-12 06:58:19
【问题描述】:

在 Perl 中,可以使用 Perl 内置函数或使用 system() 调用 shell 命令来实现某些目标。问题是,对于作为 Perl 初学者的我来说,有时很难找到与 Linux 命令等效的 Perl。
以这个为例:

cat file1 file2 | sort -u > file3

我真的很想只使用 Perl 函数来使我的 Perl 更加 Perl,但我无法轻松找出在这种情况下如何避免使用 system()。

所以我想知道,使用 Perl 库函数比使用 system() 调用有什么优势吗?哪种方式更好?

【问题讨论】:

    标签: linux perl


    【解决方案1】:

    通常使用库函数的好处是,当出现问题时,您可以给出有意义的错误消息。

    对于短期脚本或当开发资源非常宝贵时,使用系统代替是有意义的。

    【讨论】:

    • 虽然我最喜欢 mpapec 的答案,但这个似乎更适合作为公认的答案。但是 Ed Heal 提到 perl 不需要启动进程,Hynek -Pichi- Vychodil 提到系统命令在某些情况下更有效。
    • @duleshi 你现在知道如何避免system() 来电了吗?
    • @mpapec 我对你的问题感到困惑。既然你告诉我一种 Perl 方法来避免 system() 调用我的问题。我理解你的代码。你问我现在是否知道如何避免 system() 是什么意思?
    【解决方案2】:
    local $^I;
    local @ARGV = qw(file1 file2);
    open my $fh, ">", "file3" or die $!;
    my %s;
    
    # print {$fh} (LIST) # or using foreach:
    print $fh $_ for
      sort
      grep !$s{$_}++,
      <>;
    

    主要优点是可移植性和没有系统依赖性。

    更明确的版本,

    use List::MoreUtils qw(uniq);
    local $^I;
    local @ARGV = qw(file1 file2);
    open my $fh, ">", "file3" or die $!;
    
    for my $line (sort uniq readline()) {
      print $fh $line;
    }
    

    【讨论】:

    • 虽然使用诸如command for expression$_ 尤其是&lt;&gt; 之类的缩写肯定被许多人认为是非常不恰当的,但我怀疑它是否真的有助于自称为 Perl 初学者的人。老实说,我也不会在我的脚本中使用它,除非我可以确定我的任何同事都不必阅读或更改它。它是 Perl,如果我要提高效率,我会使用其他东西。那么为什么不添加几个额外的单词以保持可读性。
    • @DeVadder :我非常喜欢这个解决方案。我唯一可能做的就是插入sub uniq { my %seen; grep { ! $seen{$_}++ } @_ } 以将最后一行简化为print $fh $_ for sort uniq( &lt;&gt; );。为了学习 Perl,必须欣赏它丰富的语法。这是一个很好的例子,catsort -u 很好地结合在一起。
    • @DeVadder 虽然我是初学者,但我在问题中说我更喜欢我的代码更糟糕。我买了著名的初学者读物《Learning Perl》,读的差不多了。但是我很少练习所以我不擅长。但我确实想掌握一些高级功能。
    • @duleshi:只是我是那些不同意代码更好或更简单的 Perl 用户之一,它包含的单词或行数越少。我们的测试脚本往往变得非常庞大和复杂,我希望它们保持易于阅读,即使对于不习惯 Perl 的人来说也是如此。那是因为经常不经常使用 Perl 的同事需要修改脚本,因为他们需要在我们开发的实际软件(C++)中测试不同的东西。 Perl 拥有只写代码的灵气,这让我很恼火。 Perl 允许编写每个人都可以阅读的代码,而无需了解 Perl。
    • 但我离题了。 :) 与往常一样,mpapecs 解决方案当然有效且高效,所以不要将我的个人意见视为除此之外的任何东西。
    【解决方案3】:

    使用 perl 库。节省了处理器在生成另一个进程时的工作量。还能够在出现问题时获得更好的指示。

    【讨论】:

    • 只是为了确认。你的意思是 system() 启动一个新的子进程,而 perl 库函数没有,对吧?如果这是真的,我会很高兴的。或者我们为什么要费心深入研究 perl,因为我们可以代替系统命令。
    • @duleshi - 避免产生其他进程的开销。
    • @duleshi:是的,system() 分叉并等待孩子。
    【解决方案4】:

    如果您想执行系统命令并使其失效,我建议使用 open()。

    open(fh,"cat test.txt text_file.txt | sort -u >new_file.txt | ");
    

    这使你的程序简单易懂。perl 中为系统命令提供的支持是它的优点之一。所以最好按原样使用它,而不是为了让你的代码“Perlish”。

    【讨论】:

    • 但是作为一个简单的反例,如果有很多重复,你可以通过在读入数据时已经删除重复来节省大量内存。
    • @tripleee -u 删除重复项
    • 是的,但是cat 需要在sort -u 删除它们之前将它们全部读完,而自然的 Perl 解决方案会在读入时立即删除副本。
    【解决方案5】:

    您当然可以使用mpapec 指出的 Perl 脚本版本。但是使用Asif Idris 指向的systemopen 版本有一些优势。例如,如果您需要对大量数据进行排序,使用系统命令sort 会让您走得更远,痛苦更少。使用 perl 对几 GB 进行排序是 PITA,但对于系统命令 sort 来说没什么大不了的,您甚至会使用所有内核和更少的内存。

    【讨论】:

    • 您能解释一下为什么系统排序在处理GB数据时更好吗?或者这只是一个经验法则?很明显 perl funcs 无需启动新进程的优势在执行如此繁重的工作时变得可以忽略不计。但是为什么 perl 比较慢呢?
    • *nix sort 特别针对磁盘上的文件排序进行了优化。如果您希望对大小与 RAM 相媲美或超过的数据进行排序,那么没有什么能比得上它了。另一方面,如果你使用纯 perl,编写跨平台脚本将不需要处理命令行参数和 BSD/SYS5/GNU 版本的实用程序的输出格式。自己判断权衡。
    猜你喜欢
    • 2019-10-19
    • 1970-01-01
    • 2010-10-18
    • 2011-03-27
    • 1970-01-01
    • 1970-01-01
    • 2011-03-29
    • 2016-08-06
    相关资源
    最近更新 更多