我的bash环境中内置了一个复杂的机制,它需要在生成提示时执行几个脚本,但是当用户按Enter键开始处理命令时也是如此。我将给出一个过于简化的描述:
调试陷阱以相当有限的方式执行此操作:每次执行语句时都会触发它。
trap 'echo $BASH_COMMAND' DEBUG # example
不幸的是,这意味着当我输入时:
sleep 1; sleep 2; sleep 3
而不是处理包含整行的$BASH_COMMAND
,而是在三个不同的陷阱中得到三个睡眠。更糟糕的是:
sleep 1 | sleep 2 | sleep 3
管道设置时触发所有三个 - 在sleep 1
开始执行之前,输出可能会让您相信睡眠3正在运行。
我需要一种方法来在开始时执行脚本,处理整个命令,而且在运行prompt命令时我不会触发,但如果必须,我可以处理它。
答案 0 :(得分:0)
这个解决方案存在一个主要问题。带管道的命令(|)将完成执行陷阱,但是在陷阱过程中的背景将导致命令的处理冻结 - 你永远不会在没有点击的情况下获得提示。陷阱完成,但$ PROMPT_COMMAND从不运行。即使您在拍摄背景后立即取消了该过程,这个问题仍然存在。
这比我预期的更有趣:
LOGFILE=~/logfiles/$BASHPID
start_timer() {
if [ ! -e $LOGFILE ]; then
#You may have to adjust this to fit with your history output format:
CMD=`history | tail -1 | tr -s " " | cut -f2-1000 -d" "`
#timer2 keeps updating the status line with how long the cmd has been running
timer2 -p "$PROMPT_BNW $CMD" -u -q & echo $! > $LOGFILE
fi
}
stop_timer() {
#Unfortunately, killing a process always prints that nasty confirmation line,
#and you can't silence it by redirecting stdout and stderr to /dev/null, so you
#have to disown the process before killing it.
disown `cat $LOGFILE`
kill -9 `cat $LOGFILE`
rm -f $LOGFILE
}
trap 'start_timer' DEBUG