我使用App::Cmd构建我的CLI应用程序。
是否可以实现像docker network inspect
这样的子命令? (假设inspect
是子命令)
我具有以下用于实现命令foo bar
的代码
$ cat bin/foo
#!/usr/bin/perl
use Foo;
Foo->run;
$ cat lib/Foo.pm
package Foo;
use App::Cmd::Setup -app;
1;
$ cat lib/Foo/Command/bar.pm
package Foo::Command::bar;
use App::Cmd::Setup -command;
sub execute {
print "Hello world\n";
}
1;
我通过将foo bar baz
修改为:实现了子命令lib/Foo/Command/bar.pm
:
sub execute {
my ( $self, $opt, $args ) = @_;
my $subcommand = $args->[0];
if ( $subcommand eq 'baz' ) {
print "Subcommand baz is working\n";
}
...
}
还有更好的方法吗?
$args->[0]
方法的主要缺点是您无法自动生成--help
(foo bar
将显示与foo bar baz
相同的帮助]
换句话说,App::Cmd
被锐化为<bin_name> <command> [-?h] [long options...]
调用语法,但是我需要<bin_name> <command> <subcommand> [-?h] [long options...]
语法。
P.S。我为实验创建了Github repository
我花了一些时间在Github([1],[2])上找到一些示例代码来弄清楚这一点。对于foo bar baz
用例,您需要以下内容:
# Foo.pm is unchanged from your code
# Bar.pm is no longer a command module
$ cat lib/Foo/Command/Bar.pm
package Foo::Command::Bar;
use base qw/App::Cmd::Subdispatch/;
use constant plugin_search_path => __PACKAGE__;
# no need for execute(), this module only dispatches subcommands
# abstract() and show_desc() are still supported
1;
# Finally, a subcommand like `baz` needs its own script Baz.pm
# (mind the file location)
$ cat lib/Foo/Command/Bar/Baz.pm
package Foo::Command::Bar::Baz;
use App::Cmd::Setup -command;
sub execute {
print "Hello world\n";
}
1;