如何在 Common Lisp 中可移植地解析命令行参数和标志?
How to parse command line arguments and flags portably in Common Lisp?
我想获取并解析 Common Lisp 中的命令行参数,例如myscript -a 1 -b 2
将允许我获取值,myscript -xyz
也可以。我怎样才能做到可移植(在编译器之间)?
你可以试试unix-options
.
(ql:quickload :unix-options)
(defpackage :test
(:use :cl)
(:import-from :unix-options
:¶meters
:&free
:with-cli-options))
您可能想要 :use
包,但如果您更喜欢从中导入符号,请不要忘记 &free
和 ¶meters
。
该库定义了一个类似于传统 getopt
实用程序的 getopt
函数。但它也定义了 with-cli-options
,这有点乱。
- 第一组符号定义选项,即不存在或存在的标志;
¶meters
后的符号定义参数,后面必须跟数值;
- 未被识别为选项或参数的参数在绑定到由
&free
指定的变量的列表中可用
例如:
(in-package :test)
(defun my-program (&rest cli-args)
(with-cli-options (cli-args)
(x y z ¶meters a b &free other)
(list x y z a b other))))
这里我定义了程序的入口点。在实际程序中,您可以简单地将第一个列表留空,如下所示:
(with-cli-options () <bindings> <body>)
... 并且选项将从您的 Lisp 实现的实际命令行参数中可移植地获取。您还可以调用 (uiop:command-line-arguments)
来获得完整的命令行,这似乎支持更多的实现并将程序名称作为第一个元素。
上面的函数允许我测试解析器的行为。
请注意,例如,短选项可以分隔或连接:
(my-program "-xyz" "-a" "2" "-b" "3" "--" "something")
=> (T T T "2" "3" ("something"))
(my-program "-x" "-y" "-z" "-a" "2" "-b" "3" "--" "something")
=> (T T T "2" "3" ("something"))
注意声明为参数但未给出实际值(或者可能是,大小写不明确)的选项:
(my-program "-a" "-b")
=> (NIL NIL NIL "-b" NIL NIL)
有未知参数的警告:
(ignore-errors (my-program "-w"))
; WARNING: Invalid option: w
=> (NIL NIL NIL NIL NIL NIL)
有关详细信息,请参阅文档。
我想获取并解析 Common Lisp 中的命令行参数,例如myscript -a 1 -b 2
将允许我获取值,myscript -xyz
也可以。我怎样才能做到可移植(在编译器之间)?
你可以试试unix-options
.
(ql:quickload :unix-options)
(defpackage :test
(:use :cl)
(:import-from :unix-options
:¶meters
:&free
:with-cli-options))
您可能想要 :use
包,但如果您更喜欢从中导入符号,请不要忘记 &free
和 ¶meters
。
该库定义了一个类似于传统 getopt
实用程序的 getopt
函数。但它也定义了 with-cli-options
,这有点乱。
- 第一组符号定义选项,即不存在或存在的标志;
¶meters
后的符号定义参数,后面必须跟数值;- 未被识别为选项或参数的参数在绑定到由
&free
指定的变量的列表中可用
例如:
(in-package :test)
(defun my-program (&rest cli-args)
(with-cli-options (cli-args)
(x y z ¶meters a b &free other)
(list x y z a b other))))
这里我定义了程序的入口点。在实际程序中,您可以简单地将第一个列表留空,如下所示:
(with-cli-options () <bindings> <body>)
... 并且选项将从您的 Lisp 实现的实际命令行参数中可移植地获取。您还可以调用 (uiop:command-line-arguments)
来获得完整的命令行,这似乎支持更多的实现并将程序名称作为第一个元素。
上面的函数允许我测试解析器的行为。
请注意,例如,短选项可以分隔或连接:
(my-program "-xyz" "-a" "2" "-b" "3" "--" "something")
=> (T T T "2" "3" ("something"))
(my-program "-x" "-y" "-z" "-a" "2" "-b" "3" "--" "something")
=> (T T T "2" "3" ("something"))
注意声明为参数但未给出实际值(或者可能是,大小写不明确)的选项:
(my-program "-a" "-b")
=> (NIL NIL NIL "-b" NIL NIL)
有未知参数的警告:
(ignore-errors (my-program "-w"))
; WARNING: Invalid option: w
=> (NIL NIL NIL NIL NIL NIL)
有关详细信息,请参阅文档。