太长了;博士

太长了;博士

有人曾经告诉我在命令行上解析选项有一个标准。就像是:

./script.sh [options/flags] [command or file]

我知道,在解析 shell 脚本时,这会让生活变得更轻松,因为您可以shift通过标志,并且可以通过 访问剩下的任何内容$@ or $*,但是是否有实际的书面标准?

我看过的大多数程序都遵循这个标准,但也有一些例外,例如,ls其中ls -l /pathls /path -lls /path -l /path2都是可以接受的。

答案1

POSIX 基本定义有一个关于“实用约定" 适用于 POSIX 基本实用程序。

标准getopts效用和getopt()在解析 shell 脚本或 C 程序中的命令行时,系统接口(“C 函数”)遵循准则(在上面链接的页面的下方)。具体来说,对于getopts(作为示例):

当遇到选项末尾时,getopts实用程序应退出并返回大于零的值; shell 变量OPTIND应设置为第一个操作数的索引,"$#" +1如果没有操作数则设置为值;变量name应设置为字符。以下任何一项都应标识选项的结束:第一个--参数不是选项参数,查找不是选项参数且不以 开头的参数-,或者遇到错误。

这基本上说的是选项应首先出现,然后是操作数(您的“命令或文件”)。

以任何其他方式执行此操作都会导致使用getoptsgetopt()不可能,并且还可能使习惯使用 POSIX 方式为命令指定选项和操作数的用户感到困惑。

请注意,上述标准仅适用于 POSIX 实用程序,但因此它通常为 Unix 实用程序设置了优先级。显然,非标准 Unix 实用程序可以选择遵循或打破这一点。

例如,GNU coreutils,即使它们实现了标准实用程序,也允许诸如

$ ls Documents/ -l

如果POSIXLY_CORRECT未设置环境变量,而相同实用程序的 BSD 版本则没有设置。

这会导致以下结果在 BSD 系统上按预期工作(也就是说,如果您期望 POSIX 行为):

$ touch -- 'test' '-l'

$ ls -l test -l
-rw-r--r--  1 kk  kk  0 Jan 11 16:44 -l  
-rw-r--r--  1 kk  kk  0 Jan 11 16:44 test

但在 GNU coreutils 系统上,你会得到

$ ls -l test -l
-rw-r--r-- 1 kk kk 0 Jan 11 16:44 test

然而:

$ env POSIXLY_CORRECT=1 ls -l test -l

$ ls -l -- test -l

在 GNU 系统上也会做“正确”的事情。

答案2

太长了;博士

  • 有一个标准命令行格式
  • 它需要参数之前有选项。
  • 标准的这一部分被广泛忽视。

一个例子

我在 python 中使用过的所有三个选项解析库默认允许散布的参数并提供常见内容的说明:

  1. 现已弃用的 python 标准库模块optparse允许:

    OptionParser.enable_interspersed_args()
    

    将解析设置为在第一个非选项上不停止,从而允许使用命令参数散布开关。这是默认行为。

  2. 当前的python标准库模块argparse允许(且仅允许)散布参数。

  3. click,我目前最喜欢的图书馆,允许要禁用的散布参数

    click.Context(allow_interspersed_args=False)
    

    但在故障排除的高级部分中讨论了这种可能性子命令的未知参数

相关内容