Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Perl中实现CLI工具的最佳实践是什么?_Perl_Command Line - Fatal编程技术网

在Perl中实现CLI工具的最佳实践是什么?

在Perl中实现CLI工具的最佳实践是什么?,perl,command-line,Perl,Command Line,我正在使用Perl实现一个CLI工具。 我们在这里可以遵循哪些最佳实践?您应该使用这些实践来使代码可重用且易于理解。 应该看看使用POD来记录您的工具,遵循手册页的指导原则;至少包括以下部分:姓名、大纲、描述、作者。一旦有了合适的POD,就可以使用pod2man生成手册页,在控制台上使用perldoc your-script.pl查看文档 使用为您处理命令行选项的模块。我真的很喜欢结合使用这种方式调用--help将显示一条很好的帮助消息 确保脚本在成功与否时返回正确的退出值 下面是一个脚本的小框

我正在使用Perl实现一个CLI工具。 我们在这里可以遵循哪些最佳实践?

您应该使用这些实践来使代码可重用且易于理解。

应该看看

使用POD来记录您的工具,遵循手册页的指导原则;至少包括以下部分:姓名、大纲、描述、作者。一旦有了合适的POD,就可以使用pod2man生成手册页,在控制台上使用perldoc your-script.pl查看文档

使用为您处理命令行选项的模块。我真的很喜欢结合使用这种方式调用--help将显示一条很好的帮助消息

确保脚本在成功与否时返回正确的退出值

下面是一个脚本的小框架,它可以完成所有这些任务:

#!/usr/bin/perl

=head1 NAME

simplee - simple program

=head1 SYNOPSIS

    simple [OPTION]... FILE...

    -v, --verbose  use verbose mode
    --help         print this help message

Where I<FILE> is a file name.

Examples:

    simple /etc/passwd /dev/null

=head1 DESCRIPTION

This is as simple program.

=head1 AUTHOR

Me.

=cut

use strict;
use warnings;

use Getopt::Long qw(:config auto_help);
use Pod::Usage;

exit main();

sub main {

    # Argument parsing
    my $verbose;
    GetOptions(
        'verbose'  => \$verbose,
    ) or pod2usage(1);
    pod2usage(1) unless @ARGV;
    my (@files) = @ARGV;

    foreach my $file (@files) {
        if (-e $file) {
            printf "File $file exists\n" if $verbose;
        }
        else {
            print "File $file doesn't exist\n";
        }
    }

    return 0;
}
#/usr/bin/perl
=标题1名称
简单程序
=总目1概要
简单[选项]。。。文件
-v、 --详细使用详细模式
--帮助打印此帮助消息
其中I是一个文件名。
示例:
simple/etc/passwd/dev/null
=标题1说明
这是一个简单的程序。
=第一作者
我
=切割
严格使用;
使用警告;
使用Getopt::Long qw(:config auto_help);
使用Pod::用法;
退出main();
副总管{
#参数解析
我的$verbose;
获取选项(
'verbose'=>\$verbose,
)或POD2用法(1);
POD2用法(1),除非@ARGV;
我的(@files)=@ARGV;
foreach my$文件(@files){
如果(-e$file){
如果$verbose,则printf“File$File exists\n”;
}
否则{
打印“文件$File不存在\n”;
}
}
返回0;
}

我学到的一些经验教训:

1) 始终使用Getopt::Long

2) 通过--help提供使用帮助,最好是提供常见场景的示例。它帮助人们不知道或忘记了如何使用该工具。(也就是说,你在六个月内)

3) 除非用户很清楚为什么,否则不要长时间(>5s)不向用户输出。类似于“打印”行$Row…\n“除非($Row%1000)”的内容非常有用

4) 对于长时间运行的操作,如果可能,允许用户恢复。通过百万分之五十万,死去,然后重新开始真的很糟糕


5) 将您正在做的事情的逻辑分离到模块中,并尽可能地保留实际的.pl脚本;解析选项、显示帮助、调用基本方法等等。您不可避免地会找到一些您想要重用的东西,这使它变得非常简单

以下几点不是Perl特有的,但我发现许多Perl CL脚本在这些方面存在缺陷:

  • 使用通用命令行选项。要显示版本号,请执行-v或--version not--ver。对于递归处理-r(或者可能是-r,尽管在我的Gnu/Linux经验中-r更常见)不是-rec。如果人们能够记住参数,他们将使用您的脚本。如果您能记住“它像grep一样工作”或其他一些熟悉的实用程序,那么学习新命令很容易

  • 许多命令行工具处理“当前目录”中的“内容”(文件或目录)。虽然这很方便,但请确保还添加了用于显式标识要处理的文件或目录的命令行选项。这使得将实用程序放在管道中变得更容易,而不需要开发人员发出大量cd命令并记住它们所在的目录


  • 上有两个模块可以使编写CLI程序变得更容易:



    如果你的应用程序是基于Moose的,你也可以看看,最重要的是要有标准选项

    不要试图变得聪明,只是简单地保持一致

    如何实现这一点也很重要,但只能排在第二位


    实际上,这对于所有CLI接口来说都是非常通用的。

    作为序言,我花了3年时间为一家大型金融公司设计并实现了一个非常复杂的Perl命令行工具集。以下想法基本上是我们团队设计指南的一部分

    用户界面
  • 命令行选项:允许有尽可能多的默认值

  • 任何具有2个以上选项的命令都没有位置参数

  • 具有可读的选项名称。如果非交互式调用需要考虑命令行的长度(例如,一些未命名的遗留shell在命令行上有较短的限制),请提供较短的别名-GetOpt::Long允许轻松实现这一点

  • 至少,在“-help”消息中打印所有选项的“默认值”

    更好的是,打印所有选项的“当前”值(例如,如果参数和值随“-help”一起提供,则帮助消息将从命令行打印参数值)。这样,人们就可以为复杂的命令组装命令行字符串,并在实际运行之前通过添加“-help”对其进行验证

  • 如果程序因错误终止,请遵循Unix标准惯例,即使用非零返回代码退出

  • 如果您的程序可能会产生有用的(例如,值得捕获/grepping/whatnot)输出,请确保将所有错误/诊断消息发送到STDERR,以便它们易于分离

  • 理想情况下,允许用户通过命令行参数指定输入/输出文件,而不是强制“”重定向-这使需要使用您的命令构建复杂管道的人的生活更加简单。错误消息同上-具有日志文件选项

  • 如果命令有副作用,那么使用“whatif/no_post”选项通常是一个非常好的主意

  • 实施
  • 如前所述,不要重新发明轮子。使用标准命令行参数处理模块-MooseX::Getopt或Getopt::Long

  • 对于Getopt::Long,将所有参数作为opp分配给单个散列