如何自定义 Bash 中错误消息的颜色?

如何自定义 Bash 中错误消息的颜色?

是否可以自定义 Bash 错误消息属性?

例如,是否可以编辑.bash_profile以获取以下 Bash 错误消息

-bash: cd: foo: No such file or directory

红色的?

答案1

遗憾的是,没有PS提示变量来控制 bash 错误的呈现方式。

标准错误是解决此类问题的全面解决方案,但它如果不进行修改将无法工作,因为它有一个硬编码排除bash请继续阅读以了解原因)。此外,它还具有一定的侵入性(DLL 注入)。

希莱特要求您将其用作包装器,这对诸如 bash 内置命令不起作用cd

您的问题专门询问了 bash 错误消息,这些消息会发送到stderr,但stderr也会与任何子进程(即任何其他命令)共享。我不确定您是否想区分这两者。

这里隐藏的一个问题是,它bash本身会将提示和你的输入(回显)写入stderr。为了证明:

bash              # start a sacrificial shell
exec 2> tmpfile   # change stderr to a file
ls                # you will see no prompt, and no command echo
... 
exit              # quit sacrificial shell
cat tmpfile       # contains PS1 prompt, your commands (and any errors too)

内置函数调用(或至少应该调用)builtin_error()内部函数来打印错误,这会无条件调用fprintf()stderr因此选项很少。

无需费尽心机或打补丁bash,突出显示错误的一个简单方法是:

function _t_debug() 
{
    if [ "${BASH_COMMAND:0:6}" != "_t_err" ]; then
        _lastcmd="$BASH_COMMAND"
    fi  
}
function _t_err() 
{
    local rc=$1 nn _type _argv
    #shift; pipe=($*)
    #if [ ${#pipe[*]} -gt 1 ]; then
    #    for ((nn=1; nn<=${#pipe[*]};nn++));do
    #        rc=${pipe[$((nn-1))]}
    #        echo -n "[$nn]=$rc ";
    #        ((rc >=128)) && echo -n "($((rc-128))) "
    #    done
    #fi

    read -a _argv <<< ${_lastcmd}
    _type=$(type -t "${_argv[0]}")

    if [ -n "$_lastcmd" ]; then
        tput setf 4
        printf 'Error %s: "%s"' "${_type}" "${_lastcmd:-unknown command}"
        tput sgr 0
        printf "\n"
    fi

    ((rc >=128)) && echo "[rc=$rc ($((rc-128)))]" ||
    echo "[rc=$rc]"
}
trap '_t_err $? ${PIPESTATUS[*]}' ERR
trap '_t_debug' DEBUG

这将使用 bash DEBUGtrap 在执行前缓存每个命令行,并使用 trapERR输出非零的返回代码。但对于某些 bash 内置命令(特别是复合命令while/case/for/if以及更多信息,请参阅手册页)。

我在我的 中使用了它的变体.profile,尽管我使用了pipe[]/PIPESTATUS[]上面注释掉的部分,但它与上面介绍的 DEBUG 陷阱不兼容。如果您注释掉 ,trap DEBUG则可以使用它来显示管道中每个命令的返回代码。

(此外,由于它被引用,command_not_found函数钩子是 bash-4.0+。)

答案2

以下解决方案可以满足您的需要:

# whatever_command 2> >(while read line; do echo -e "\e[01;31m$line\e[0m" >&2; done)

基本上,上面的命令打印标准错误红色的。

查看下面的屏幕截图:

在此处输入图片描述

我不知道如何使它永久生效。但是,这肯定会给你一些提示。

答案3

你可能想看看标准错误以寻求更持久的解决方案。

答案4

也许你可以尝试希莱特-我认为这是最简单的解决方案之一。

相关内容