Getopt::Long 可以容纳变量选项名称吗?

发布于 2024-11-15 16:53:44 字数 124 浏览 2 评论 0原文

我正在编写一个脚本,可以执行以下操作:

script-name --resource1=xxx --resource2=xxx

但这最多可以达到 50+。有没有办法让 GetOpt 接受动态选项名称?

I am writing a script that can do something like:

script-name --resource1=xxx --resource2=xxx

But this can go up to 50+. Is there a way to make GetOpt accept dynamic option names?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

寄意 2024-11-22 16:53:44

如何自动生成 Getopt::Long 的选项列表,如下例所示?由于选项列表可能会很长,因此使用 Getopt::ArgvFile 允许您可以为配置文件提供选项,而不是在命令行上指定它们。

use Getopt::Long;
use Getopt::ArgvFile;
use Data::Dump;

my @n = (1 .. 10);    # how many resources allowed
my %opts = (
    port                  => ':i',
    http_version          => ':s',
    invert_string         => ':s',
    ssl                   => '',
    expect                => ':s',
    string                => ':s',
    post_data             => ':s',
    max_age               => ':i',
    content_type          => ':s',
    regex                 => ':s',
    eregi                 => ':s',
    invert_regex          => '',
    authorization         => ':s',
    useragent             => ':s',
    pagesize              => ':s',
    expected_content_type => ':s',
    verify_xml            => '',
    rc                    => ':i',
    hostheader            => ':s',
    cookie                => ':s',
    encoding              => ':s',
    max_redirects         => ':i',
    onredirect_follow     => ':i',
    yca_cert              => ':s',
);

my %args = ();
GetOptions(\%args,
    map {
        my $i = $_;
        ( "resource$i:s", map { "resource${i}_$_$opts{$_}" } keys %opts )
    } @n
) or die;

dd \%args;

What about auto-generating the options list for Getopt::Long like example below? Since the list of options will be likely pretty long, using Getopt::ArgvFile allow you to supply configuration file with options instead of specifying them on command-line.

use Getopt::Long;
use Getopt::ArgvFile;
use Data::Dump;

my @n = (1 .. 10);    # how many resources allowed
my %opts = (
    port                  => ':i',
    http_version          => ':s',
    invert_string         => ':s',
    ssl                   => '',
    expect                => ':s',
    string                => ':s',
    post_data             => ':s',
    max_age               => ':i',
    content_type          => ':s',
    regex                 => ':s',
    eregi                 => ':s',
    invert_regex          => '',
    authorization         => ':s',
    useragent             => ':s',
    pagesize              => ':s',
    expected_content_type => ':s',
    verify_xml            => '',
    rc                    => ':i',
    hostheader            => ':s',
    cookie                => ':s',
    encoding              => ':s',
    max_redirects         => ':i',
    onredirect_follow     => ':i',
    yca_cert              => ':s',
);

my %args = ();
GetOptions(\%args,
    map {
        my $i = $_;
        ( "resource$i:s", map { "resource${i}_$_$opts{$_}" } keys %opts )
    } @n
) or die;

dd \%args;
瞄了个咪的 2024-11-22 16:53:44

它可以使用相同的选项名称重复吗?

例如:脚本名称 --resource=xxx --resource=xxx

Would it work with the same option name repeated?

For example: script-name --resource=xxx --resource=xxx

对岸观火 2024-11-22 16:53:44

是的,因为我刚刚想出了如何自己做,因为我想接受 -# 参数,而 Getopt::Long 不接受选项名称的正则表达式。这就是我所做的:

use Getopt::Long qw(:config pass_through);

my $ret=GetOptions(
    \%gops,
    'lines|l',  # lines/records to display
    ... cut ...
    '<>' => \&filearg,          # Handle file names also attach current options
);

然后定义了 filearg() 函数:

sub filearg {
    my $arg=shift;

    # First see if it is a number as in -20 as shortcut for -l 20
        if ($arg =~ /^--?(\d)+$/) {
        $gops{'lines'}=$1;
    } elsif (-f "$arg" && -r "$arg") {
        my %ops=%gops;
        $fops{$arg}=\%ops;
        push(@files, $arg);
    } else {
        push(@badargs, $arg);
    }
    return(undef);
}

所以需要的是 pass_through 选项,检查您想要的内容并在看到时设置这些内容。上面我有未定义的选项传递给我的函数。我将其用于文件检查和特殊选项 -#,其中 # 是某个整数。如果不匹配,我将添加到 badargs 数组中,因为这样做不会导致 GetOptions 失败,因此我必须在 GetOptions 返回后检查此数组以查看是否发现错误。您还可以通过使用 die("!FINISH"); 结束回调函数来使其在选项错误时结束,这将导致 GetOptions 终止脚本。

我使用它的目的是能够拥有类似 -20 FILE1 -30 FILE2 的功能,因此可以覆盖后续文件的选项。我看到您可以通过检查选项名称的第一部分然后检查值来执行类似的操作。因此,如果您的所有选项都以 --resource 开头,那么在您的函数中查找类似的内容: /^--?(resource\w+)=(.*)$/ 然后添加到选项数组中。

无论如何,希望这会有所帮助。

Yes, as I just figured out how to do it myself as I wanted to accept a -# argument and Getopt::Long doesn't accept regex for an option name. So this is what I did:

use Getopt::Long qw(:config pass_through);

my $ret=GetOptions(
    \%gops,
    'lines|l',  # lines/records to display
    ... cut ...
    '<>' => \&filearg,          # Handle file names also attach current options
);

I then defined the filearg() function:

sub filearg {
    my $arg=shift;

    # First see if it is a number as in -20 as shortcut for -l 20
        if ($arg =~ /^--?(\d)+$/) {
        $gops{'lines'}=$1;
    } elsif (-f "$arg" && -r "$arg") {
        my %ops=%gops;
        $fops{$arg}=\%ops;
        push(@files, $arg);
    } else {
        push(@badargs, $arg);
    }
    return(undef);
}

So what is needed is the pass_through option, a check for what you want and setting those things when seen. Above I had undefined options passed to my function. I use this for file checks and for a special option -# where # is some integer. If it doesn't match I add to a badargs array, as doing this will not cause GetOptions to fail, so I have to check this array after the return from GetOptions to see if errors were seen. You can also have it end on option error by ending the callback function with die("!FINISH"); which will cause GetOptions to terminate the script.

What I use it for is the ability to have something like -20 FILE1 -30 FILE2, so options can be overridden for subsequent files. I see you being able to do something similar with a check for the first part of the option name and then the value. So if all of your options start with --resource then look for something like this in your function: /^--?(resource\w+)=(.*)$/ and then add into option array.

Anyway, hope this helps.

倾`听者〃 2024-11-22 16:53:44

另一种尝试方法是仅使用某种配置文件。考虑到您计划拥有大量信息,这似乎可能是编写和解析最简单的方法。

Another method to try would be to just use some sort of configuration file. It seems like this might be the easiest method to both write and parse, given that you plan on having a large amount of information.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文