OpenBSD 中的“setaf”功能没有足够的参数

OpenBSD 中的“setaf”功能没有足够的参数

我想改变外壳中的文本颜色。我可以用来tput获取正确的转义码。例如,

echo "$(tput setaf 5)My text$(tput sgr0)"

输出My text呈粉红色调。

这在 Linux、macOS、FreeBSD、NetBSD 和 Solaris 上运行良好。然而,在 OpenBSD 7.2 上,我收到以下错误:

tput: not enough arguments (3) for capability `setaf'

根据OpenBSD 文档tputterminfo,该属性应在或中定义termcap。我没有看到setaf定义的文档termcap,所以我假设tput解释setaf的文档terminfo。根据这些文档:

要更改 Tektronix 类型终端上的当前前景色或背景色,请使用塞塔夫(设置 ANSI 前景)和塞塔布(设置 ANSI 背景)或塞特夫(设置前景)和设定值(设置背景)。它们采用一个参数,即颜色编号。

这与错误消息告诉我的内容相冲突。另一方面,我可以使用tput setaf 5 0 0and ,无论最后两个参数如何,前景色都会更改为粉红色。

为什么tputOpenBSD 上需要三个参数,这两个额外的参数意味着什么?

答案1

从我记事起,tput在各种 UNIX 类型系统(二十年?可能更久)上使用的标准期望是:

  • 后面需要tput setaf一个数字来指示要使用的 ANSI 颜色编号。其他任何事情都可能是一个错误。
  • tput sgr0不需要参数。
  • 您可以链接它们 ( tput setaf 5 sgr0),但这种特定的构造没有任何意义,因为您将发出立即重置的颜色更改。

在你的情况下,我会重申,tput setaf需要多个号码可能是一个错误

在我的基于 Debian 的系统(bullseye)上,我发现这tput setaf 5 0 0是被接受的,意外的尾随值被忽略(没有错误),因此您可能能够在不破坏其他系统的情况下满足 OpenBSD 错误。 (这同样适用于其他tput命令:接受但忽略附加的尾随参数。)但是,如果情况并非总是如此,这样的代码可能会提供合适但必要的解决方法:

# Work around OpenBSD bug https://gitlab.com/jschx/ufetch/-/merge_requests/61
tputbug=; tput setaf 0 >/dev/null 2>&1 || tputbug='0 0'

tput setaf 2 $tputbug

顺便说一句,如果您要使用大量颜色代码,我的建议是将它们捕获在变量中,以便命令执行针对每种颜色执行一次,而不是每行执行一次:

magenta=$(tput setaf 5 $tputbug)
normal=$(tput sgr0)

echo "${magenta}My text${normal}"

其他读者请注意:变量通常不需要大括号($magenta这是完全可以接受的),但在这种情况下,它们用于将变量名称与紧随其后的文本分隔开。否则,您将有一个名为 的未设置变量$magentaMy

答案2

正如托马斯·迪基在《他的评论对于这个问题,这是一个已知的错误tput错误地计算了所需的参数数量,已经向 OpenBSD 报告;这是除了OpenBSD 的其他几个问题tput这基本上是 OpenBSD 的结果tput 已经过时了

看起来这个错误已经被其他人遇到过很多次了([1] [2] [3] [4] [5])。显然,正确的解决方案是修复 OpenBSD 中的这个错误,但我不知道如何做到这一点。

我看到了三种可能的解决方法:

  • 斯图尔特·亨德森OpenBSD 邮件列表中推荐用作tput setaf 5 0 0解决方法,其中最后两个参数是假的。这在 OpenBSD 上运行良好,但在其他系统上会导致错误,这意味着您必须检测 OpenBSD 并动态更改调用tput.
  • TERM=xterm如果检测到 OpenBSD 正在运行则设置。缺点是 OpenBSD 用户只有 8 种颜色。
  • 检查是否返回错误,并根据错误tput setaf 5更改调用方式。tput

就我而言,我不会花费任何精力尝试解决或解决该问题。如果我的用户遇到这个问题,他们可以选择禁用我的程序的颜色功能,恢复 OpenBSD 上的错误报告,或者尝试自己修复 OpenBSD 中的错误。

相关内容