在编写 CLI 工具时,我面临着一个难题。
该工具应该检测图像中的面部并自动模糊它们。然而,有时只需执行其中一项操作即可使用外部工具手动标记其他面。所以我想支持三种行为:
- 检测人脸并一次性对其进行模糊处理
- 仅检测人脸
- 只模糊脸部
我解决这个问题的想法是两个互斥的选项,比如--only-detect
和--only-blur
。
然而,一位同事建议使用--detect
和可能更有意义--blur
,因此使用这两个选项会导致与不使用相同的行为,但我发现这不太直观。
我现在的问题是:我可以遵循任何惯例来做出这个决定吗?我找到了POSIX 实用程序约定,并且他们确实提到了互斥的群体,但这里没有任何帮助。
答案1
POSIX 只是说(关于 POSIX 实用程序中互斥的命令行选项):
使用冲突的互斥参数会产生未定义的结果,除非实用程序描述另有指定。
某些命令行工具具有冲突的命令行选项(例如同时有一个--silent
选项和一个--verbose
选项)。如果在调用该工具时同时使用这两个选项,如果允许,则最后一个解析的选项(该行的最后一个选项)通常会获胜。
将使用--blur
和 的最后一个。--detect
该文档将指定哪些选项是排他的。
例如,ls -l -C
与进行比较。ls -C -l
其他工具只是禁止冲突的命令行选项,在标准错误流上向用户提供诊断消息,并在发生这种情况时以非零退出代码退出。
如果同时使用--blur
和,您的代码将会出错。--detect
这是在例如cut
具有冲突标志-b
、-c
和 的情况下完成的-f
。
某些工具可能会根据调用的名称提供不同的效果。因此,您的工具可以有两个名称(硬链接),一个名为detectface
,另一个名为blurface
.这些将是完全相同的二进制文件,但程序将确定调用它的名称以确定要执行的操作。
这在系统上很常见,其中某些 shell 伪装成/bin/sh
(POSIX shell)和自身(例如bash
在 Linux 上或ksh
OpenBSD 上),并且sh
在调用时切换到“POSIX 模式” sh
,或者您可能有一个编译器可以同时编译 C和 C++ 代码,并根据它是否被调用为cc
或c++
等来切换模式(gcc
和都clang
执行此操作)。
答案2
我会问自己,在大多数情况下,用户希望程序做什么,并使其成为默认行为。当未指定选项时,应自动触发此默认行为。另一方面如果有一个指定的选项,没有什么除非使用选项指定,否则应由命令完成。
这是我认为的反例极度贫穷编程:
avconv -i file.avi
输出有关视频文件的一些信息,-i
设置输入文件,并且由于没有指定输出,avconv
因此您只需要信息。
avconv file.avi
覆盖您珍贵的视频,没有任何警告或进行备份,因为avconv
故意将参数作为输出文件并写入它无论,即使没有什么可写的。
我认为你说对了。
这就是我所说的直觉。如果默认行为是
- 检测和模糊:
command
并
command --detect --blur
检测并模糊command --detect
只检测command --blur
只会模糊
- 只有一个,例如用于检测:
command
并且
command --detect
只检测command --blur
只会模糊command --detect --blur
确实检测和模糊,如果你觉得这很有用,还有command --detectblur
一个简写
我还定义了简短的选项-d
,-b
以便用户可以调用command -bd
来设置这两个选项,无论默认行为是什么。