你如何处理命令行选项和配置文件?

时间:2022-08-06 00:12:45

What packages do you use to handle command line options, settings and config files?

您使用什么包来处理命令行选项,设置和配置文件?

I'm looking for something that reads user-defined options from the command line and/or from config files.

我正在寻找从命令行和/或配置文件中读取用户定义选项的东西。

The options (settings) should be dividable into different groups, so that I can pass different (subsets of) options to different objects in my code.

选项(设置)应该可以分为不同的组,以便我可以将不同的(子集)选项传递给我的代码中的不同对象。

I know of boost::program_options, but I can't quite get used to the API. Are there light-weight alternatives?

我知道boost :: program_options,但我不太习惯API。有轻量的替代品吗?

(BTW, do you ever use a global options object in your code that can be read from anywhere? Or would you consider that evil?)

(顺便说一句,您是否曾在代码中使用可从任何地方读取的全局选项对象?或者您会认为这是邪恶的吗?)

9 个解决方案

#1


Well, you're not going to like my answer. I use boost::program_options. The interface takes some getting used to, but once you have it down, it's amazing. Just make sure to do boatloads of unit testing, because if you get the syntax wrong you will get runtime errors.

好吧,你不会喜欢我的回答。我使用boost :: program_options。界面需要一些习惯,但是一旦你把它弄下来,它就太棒了。只要确保进行大量的单元测试,因为如果你的语法错误,你将会遇到运行时错误。

And, yes, I store them in a singleton object (read-only). I don't think it's evil in that case. It's one of the few cases I can think of where a singleton is acceptable.

并且,是的,我将它们存储在单个对象中(只读)。在这种情况下,我不认为这是邪恶的。这是我能想到的单身人士可以接受的少数案例之一。

#2


At Google, we use gflags. It doesn't do configuration files, but for flags, it's a lot less painful than using getopt.

在谷歌,我们使用gflags。它不会执行配置文件,但对于标志,它比使用getopt要痛苦得多。

#include <gflags/gflags.h>
DEFINE_string(server, "foo", "What server to connect to");
int main(int argc, char* argv[]) {
    google::ParseCommandLineFlags(&argc, &argv, true);
    if (!server.empty()) {
        Connect(server);
    }
}

You put the DEFINE_foo at the top of the file that needs to know the value of the flag. If other files also need to know the value, you use DECLARE_foo in them. There's also pretty good support for testing, so unit tests can set different flags independently.

您将DEFINE_foo放在需要知道该标志值的文件的顶部。如果其他文件也需要知道该值,则在其中使用DECLARE_foo。对测试也有很好的支持,因此单元测试可以独立设置不同的标志。

#3


For command lines and C++, I've been a fan of TCLAP: Templatized Command Line Argument Parser.

对于命令行和C ++,我一直是TCLAP的粉丝:Templatized Command Line Argument Parser。

http://sourceforge.net/projects/tclap/

#4


If Boost is overkill for you, GNU Gengetopt is probably, too, but IMHO, it's a fun tool to mess around with.

如果Boost对你来说太过分了,那么GNU Gengetopt也可能,但恕我直言,这是一个有趣的工具。

And, I try to stay away from global options objects, I prefer to have each class read its own config. Besides the whole "Globals are evil" philosophy, it tends to end up becoming an ever-growing mess to have all of your configuration in one place, and also it's harder to tell what configuration variables are being used where. If you keep the configuration closer to where it's being used, it's more obvious what each one is for, and easier to keep clean.

而且,我试图远离全局选项对象,我更喜欢让每个类都读取自己的配置。除了整个“全球化是邪恶的”哲学之外,它往往最终成为一个不断增长的混乱,将所有配置集中在一个地方,并且更难分辨哪些配置变量在哪里使用。如果您将配置保持在更接近使用位置的位置,则每个配置的位置更为明显,并且更容易保持清洁。

(As to what I use, personally, for everything recently it's been a proprietary command line parsing library that somebody else at my company wrote, but that doesn't help you much, unfortunately)

(关于我个人使用的内容,最近它是一个专有的命令行解析库,我公司的其他人写过,但不幸的是,这对你没什么帮助)

#5


I've been using TCLAP for a year or two now, but randomly I stumbled across ezOptionParser. ezOptionParser doesn't suffer from "it shouldn't have to be this complex"-syndrome the same way that other option parsers do.

我现在一直在使用TCLAP一两年,但我偶然发现了ezOptionParser。 ezOptionParser不像其他选项解析器那样遭受“它不应该是这种复杂”的综合症。

I'm pretty impressed so far and I'll likely be using it going forward, specifically because it supports config files. TCLAP is a more sophisticated library, but the simplicity and extra features from ezOptionParser is very compelling.

到目前为止我印象非常深刻,我可能会继续使用它,特别是因为它支持配置文件。 TCLAP是一个更复杂的库,但ezOptionParser的简单性和额外功能非常引人注目。

Other perks from its website include (as of 0.2.0):

其网站的其他优惠包括(截至0.2.0):

  • Pretty printing of parsed inputs for debugging.
  • 漂亮的解析输入打印用于调试。

  • Auto usage message creation in three layouts (aligned, interleaved or staggered).
  • 以三种布局(对齐,交错或交错)创建自动使用消息。

  • Single header file implementation.
  • 单头文件实现。

  • Dependent only on STL.
  • 仅依赖于STL。

  • Arbitrary short and long option names (dash '-' or plus '+' prefixes not required).
  • 任意短期和长期选项名称(不需要短划线' - '或加'+'前缀)。

  • Arbitrary argument list delimiters.
  • 任意参数列表分隔符。

  • Multiple flag instances allowed.
  • 允许多个标志实例。

  • Validation of required options, number of expected arguments per flag, datatype ranges, user defined ranges, membership in lists and case for string lists.
  • 验证所需选项,每个标志的预期参数数,数据类型范围,用户定义的范围,列表中的成员资格以及字符串列表的大小写。

  • Validation criteria definable by strings or constants.
  • 验证标准可由字符串或常量定义。

  • Multiple file import with comments.
  • 带注释的多个文件导入。

  • Exports to file, either set options or all options including defaults when available.
  • 导出到文件,设置选项或所有选项,包括默认值(如果可用)。

  • Option parse index for order dependent contexts.
  • 选项解析依赖于订单的上下文的索引。

#6


GNU getopt is pretty nice. If you want a C++ feel, consider getoptpp which is a wrapper around the native getopt. As far as configuration file is concerned, you should try to make it as stupid as possible so that parsing is easy. If you are bit considerate, you might want to use yaac&lex but that would be really a big bucks for small apps.

GNU getopt很不错。如果你想要一个C ++的感觉,可以考虑getoptpp,它是本机getopt的包装器。就配置文件而言,您应尽量使其尽可能愚蠢,以便轻松解析。如果你有点体贴,你可能想要使用yaac和lex,但这对于小型应用来说真的是一大笔钱。

I also would like to suggest that you should support both config files and command line options in your application. Config files are better for those options which are to be changed less frequently. Command-line options are good when you want to pass the immediate changing arguments (typically when you are creating a app, which would be called by some other program.)

我还建议您应该在应用程序中同时支持配置文件和命令行选项。配置文件更适合那些不经常更改的选项。当您想要传递即时更改的参数时(通常在创建应用程序时,命令行选项很好),这将由其他程序调用。)

#7


If you are working with Visual Studio 2005 on x86 and x64 Windows there is some good Command Line Parsing utilities in the SimpleLibPlus library. I have used it and found it very useful.

如果您在x86和x64 Windows上使用Visual Studio 2005,那么SimpleLibPlus库中有一些很好的命令行解析实用程序。我使用它并发现它非常有用。

#8


Not sure about command line argument parsing. I have not needed very rich capabilities in that area and have generally rolled my own to save adding more dependencies to my software. Depending upon what your needs are you may or may not want to try this route. The C++ programs I have written are generally not invoked from the command line.

不确定命令行参数解析。我不需要在该领域具有非常丰富的功能,并且通常自己动手以节省为我的软件添加更多依赖项。根据您的需求,您可能会或可能不想尝试这条路线。我编写的C ++程序通常不会从命令行调用。

On the other hand, for a config file you really can't beat an XML based format. It's readable, extensible, structured, etc... :) Plus there are lots of XML parsers out there. Despite the fact it is a C library, I tend to use libxml2 from xmlsoft.org.

另一方面,对于配置文件,您实际上无法击败基于XML的格式。它是可读的,可扩展的,结构化的......等等。还有很多XML解析器。尽管它是一个C库,但我倾向于使用xmlsoft.org中的libxml2。

#9


Try Apache Ant. Its primary usage is Java projects, but there isn't anything Java about it, and its usable for almost anything.

试试Apache Ant。它的主要用途是Java项目,但没有任何关于它的Java,它几乎可用于任何东西。

Usage is fairly simple and you've got a lot of community support too. It's really good at doing things the way you're asking.

用法非常简单,你也得到了很多社区支持。按照你的要求做事真的很擅长。

As for global options in code, I think they're quite necessary and useful. Don't misuse them, though.

至于代码中的全局选项,我认为它们非常必要且有用。但是,不要滥用它们。

#1


Well, you're not going to like my answer. I use boost::program_options. The interface takes some getting used to, but once you have it down, it's amazing. Just make sure to do boatloads of unit testing, because if you get the syntax wrong you will get runtime errors.

好吧,你不会喜欢我的回答。我使用boost :: program_options。界面需要一些习惯,但是一旦你把它弄下来,它就太棒了。只要确保进行大量的单元测试,因为如果你的语法错误,你将会遇到运行时错误。

And, yes, I store them in a singleton object (read-only). I don't think it's evil in that case. It's one of the few cases I can think of where a singleton is acceptable.

并且,是的,我将它们存储在单个对象中(只读)。在这种情况下,我不认为这是邪恶的。这是我能想到的单身人士可以接受的少数案例之一。

#2


At Google, we use gflags. It doesn't do configuration files, but for flags, it's a lot less painful than using getopt.

在谷歌,我们使用gflags。它不会执行配置文件,但对于标志,它比使用getopt要痛苦得多。

#include <gflags/gflags.h>
DEFINE_string(server, "foo", "What server to connect to");
int main(int argc, char* argv[]) {
    google::ParseCommandLineFlags(&argc, &argv, true);
    if (!server.empty()) {
        Connect(server);
    }
}

You put the DEFINE_foo at the top of the file that needs to know the value of the flag. If other files also need to know the value, you use DECLARE_foo in them. There's also pretty good support for testing, so unit tests can set different flags independently.

您将DEFINE_foo放在需要知道该标志值的文件的顶部。如果其他文件也需要知道该值,则在其中使用DECLARE_foo。对测试也有很好的支持,因此单元测试可以独立设置不同的标志。

#3


For command lines and C++, I've been a fan of TCLAP: Templatized Command Line Argument Parser.

对于命令行和C ++,我一直是TCLAP的粉丝:Templatized Command Line Argument Parser。

http://sourceforge.net/projects/tclap/

#4


If Boost is overkill for you, GNU Gengetopt is probably, too, but IMHO, it's a fun tool to mess around with.

如果Boost对你来说太过分了,那么GNU Gengetopt也可能,但恕我直言,这是一个有趣的工具。

And, I try to stay away from global options objects, I prefer to have each class read its own config. Besides the whole "Globals are evil" philosophy, it tends to end up becoming an ever-growing mess to have all of your configuration in one place, and also it's harder to tell what configuration variables are being used where. If you keep the configuration closer to where it's being used, it's more obvious what each one is for, and easier to keep clean.

而且,我试图远离全局选项对象,我更喜欢让每个类都读取自己的配置。除了整个“全球化是邪恶的”哲学之外,它往往最终成为一个不断增长的混乱,将所有配置集中在一个地方,并且更难分辨哪些配置变量在哪里使用。如果您将配置保持在更接近使用位置的位置,则每个配置的位置更为明显,并且更容易保持清洁。

(As to what I use, personally, for everything recently it's been a proprietary command line parsing library that somebody else at my company wrote, but that doesn't help you much, unfortunately)

(关于我个人使用的内容,最近它是一个专有的命令行解析库,我公司的其他人写过,但不幸的是,这对你没什么帮助)

#5


I've been using TCLAP for a year or two now, but randomly I stumbled across ezOptionParser. ezOptionParser doesn't suffer from "it shouldn't have to be this complex"-syndrome the same way that other option parsers do.

我现在一直在使用TCLAP一两年,但我偶然发现了ezOptionParser。 ezOptionParser不像其他选项解析器那样遭受“它不应该是这种复杂”的综合症。

I'm pretty impressed so far and I'll likely be using it going forward, specifically because it supports config files. TCLAP is a more sophisticated library, but the simplicity and extra features from ezOptionParser is very compelling.

到目前为止我印象非常深刻,我可能会继续使用它,特别是因为它支持配置文件。 TCLAP是一个更复杂的库,但ezOptionParser的简单性和额外功能非常引人注目。

Other perks from its website include (as of 0.2.0):

其网站的其他优惠包括(截至0.2.0):

  • Pretty printing of parsed inputs for debugging.
  • 漂亮的解析输入打印用于调试。

  • Auto usage message creation in three layouts (aligned, interleaved or staggered).
  • 以三种布局(对齐,交错或交错)创建自动使用消息。

  • Single header file implementation.
  • 单头文件实现。

  • Dependent only on STL.
  • 仅依赖于STL。

  • Arbitrary short and long option names (dash '-' or plus '+' prefixes not required).
  • 任意短期和长期选项名称(不需要短划线' - '或加'+'前缀)。

  • Arbitrary argument list delimiters.
  • 任意参数列表分隔符。

  • Multiple flag instances allowed.
  • 允许多个标志实例。

  • Validation of required options, number of expected arguments per flag, datatype ranges, user defined ranges, membership in lists and case for string lists.
  • 验证所需选项,每个标志的预期参数数,数据类型范围,用户定义的范围,列表中的成员资格以及字符串列表的大小写。

  • Validation criteria definable by strings or constants.
  • 验证标准可由字符串或常量定义。

  • Multiple file import with comments.
  • 带注释的多个文件导入。

  • Exports to file, either set options or all options including defaults when available.
  • 导出到文件,设置选项或所有选项,包括默认值(如果可用)。

  • Option parse index for order dependent contexts.
  • 选项解析依赖于订单的上下文的索引。

#6


GNU getopt is pretty nice. If you want a C++ feel, consider getoptpp which is a wrapper around the native getopt. As far as configuration file is concerned, you should try to make it as stupid as possible so that parsing is easy. If you are bit considerate, you might want to use yaac&lex but that would be really a big bucks for small apps.

GNU getopt很不错。如果你想要一个C ++的感觉,可以考虑getoptpp,它是本机getopt的包装器。就配置文件而言,您应尽量使其尽可能愚蠢,以便轻松解析。如果你有点体贴,你可能想要使用yaac和lex,但这对于小型应用来说真的是一大笔钱。

I also would like to suggest that you should support both config files and command line options in your application. Config files are better for those options which are to be changed less frequently. Command-line options are good when you want to pass the immediate changing arguments (typically when you are creating a app, which would be called by some other program.)

我还建议您应该在应用程序中同时支持配置文件和命令行选项。配置文件更适合那些不经常更改的选项。当您想要传递即时更改的参数时(通常在创建应用程序时,命令行选项很好),这将由其他程序调用。)

#7


If you are working with Visual Studio 2005 on x86 and x64 Windows there is some good Command Line Parsing utilities in the SimpleLibPlus library. I have used it and found it very useful.

如果您在x86和x64 Windows上使用Visual Studio 2005,那么SimpleLibPlus库中有一些很好的命令行解析实用程序。我使用它并发现它非常有用。

#8


Not sure about command line argument parsing. I have not needed very rich capabilities in that area and have generally rolled my own to save adding more dependencies to my software. Depending upon what your needs are you may or may not want to try this route. The C++ programs I have written are generally not invoked from the command line.

不确定命令行参数解析。我不需要在该领域具有非常丰富的功能,并且通常自己动手以节省为我的软件添加更多依赖项。根据您的需求,您可能会或可能不想尝试这条路线。我编写的C ++程序通常不会从命令行调用。

On the other hand, for a config file you really can't beat an XML based format. It's readable, extensible, structured, etc... :) Plus there are lots of XML parsers out there. Despite the fact it is a C library, I tend to use libxml2 from xmlsoft.org.

另一方面,对于配置文件,您实际上无法击败基于XML的格式。它是可读的,可扩展的,结构化的......等等。还有很多XML解析器。尽管它是一个C库,但我倾向于使用xmlsoft.org中的libxml2。

#9


Try Apache Ant. Its primary usage is Java projects, but there isn't anything Java about it, and its usable for almost anything.

试试Apache Ant。它的主要用途是Java项目,但没有任何关于它的Java,它几乎可用于任何东西。

Usage is fairly simple and you've got a lot of community support too. It's really good at doing things the way you're asking.

用法非常简单,你也得到了很多社区支持。按照你的要求做事真的很擅长。

As for global options in code, I think they're quite necessary and useful. Don't misuse them, though.

至于代码中的全局选项,我认为它们非常必要且有用。但是,不要滥用它们。