是否可以自定义 Bash 错误消息属性?
例如,是否可以编辑.bash_profile以获取以下 Bash 错误消息
-bash: cd: foo: No such file or directory
Run Code Online (Sandbox Code Playgroud)
红色的?
遗憾的是,没有PS提示变量来控制 bash 错误的显示方式。
stderred是针对此类问题的综合解决方案,但如果不进行修改,它就无法工作,因为它有一个硬编码的排除(bash请继续阅读以了解原因)。而且它有点侵入性(DLL 注入)。
hilite要求您将它用作包装器,这不适用于 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)
Run Code Online (Sandbox Code Playgroud)
内置调用(或至少应该调用)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
Run Code Online (Sandbox Code Playgroud)
这使用 bashDEBUG陷阱在执行前缓存每个命令行,并ERR在非零时使用陷阱输出返回代码。但这对于某些 bash 内置命令(特别是复合命令:while/case/for/if等等,请参阅手册页)不会。
我在我的 中使用了它的变体.profile,尽管我使用了pipe[]/PIPESTATUS[]上面注释掉的位,但它与上面介绍的 DEBUG 陷阱不兼容。如果注释掉,trap DEBUG则可以使用它来显示管道中每个命令的返回代码。
(另外,由于它被引用,所以command_not_found函数钩子是 bash-4.0+。)
| 归档时间: |
|
| 查看次数: |
9905 次 |
| 最近记录: |