我的 bash 环境中内置了一个复杂的机制,当提示符生成时,以及当用户按 Enter 键开始处理命令时,该机制都需要执行几个脚本。我给出一个过于简单的描述:
调试陷阱以相当有限的方式实现这一点:每次执行语句时它都会触发。
trap 'echo $BASH_COMMAND' DEBUG # example only
不幸的是,这意味着当我输入以下内容时:
sleep 1; sleep 2; sleep 3
我没有处理包含整行的 $BASH_COMMAND,而是在三个不同的陷阱中得到了三个睡眠。更糟糕的是:
sleep 1 | sleep 2 | sleep 3
在管道设置时触发所有三个 - 在 sleep 1 开始执行之前,输出可能会让您相信 sleep 3 正在运行。
我需要一种方法来在开始时就执行脚本,处理整个命令,并且我宁愿它不在运行提示命令时触发,但如果必须的话我可以处理它。
答案1
不是很漂亮,但如果你真的需要这个,你可以PROMPT_COMMAND
在调试陷阱之外使用它来摆脱额外的调用:
trap 'debug_hook' DEBUG
debug_hook()
{
[ -n "$debug_hook_on" ] || return
debug_hook_on=""
echo hook # cmds to run ...
}
PROMPT_COMMAND='debug_hook_on=1'
现在:
$ echo 1 ; echo 2 | cat
hook
1
2
但我们仍然无法访问整个输入行:$BASH_COMMAND
只是echo 1
。
另一个灵感来自本文是使用 readline 绑定来访问整行:
$ bind -x '"\C-o":hook'
$ hook(){ echo "hook: $READLINE_LINE"; }
$ bind 'RETURN: "\C-o\n"'
现在它可以工作了:
hook: echo 1; echo 2
$ echo 1; echo 2
1
2
不过要记住一件事:对于多行输入,它会为每一行调用一次,这可能不是您想要的(可以结合使用两种方法)。