在bash中:在不使用调试陷阱的情况下处理每个命令行?

在bash中:在不使用调试陷阱的情况下处理每个命令行?,bash,debugging,command-line,shell-trap,Bash,Debugging,Command Line,Shell Trap,我在bash环境中内置了一个复杂的机制,它需要在生成提示时执行两个脚本,但也需要在用户点击enter开始处理命令时执行。我将给出一个过于简单的描述: 调试陷阱以一种相当有限的方式完成这项工作:它在每次执行语句时都会触发 trap 'echo $BASH_COMMAND' DEBUG # example 不幸的是,这意味着当我键入以下内容时: sleep 1; sleep 2; sleep 3 我没有处理包含整行的$BASH_命令,而是在三个不同的陷阱中获得三个睡眠。更糟糕的是: sleep

我在bash环境中内置了一个复杂的机制,它需要在生成提示时执行两个脚本,但也需要在用户点击enter开始处理命令时执行。我将给出一个过于简单的描述:

调试陷阱以一种相当有限的方式完成这项工作:它在每次执行语句时都会触发

trap 'echo $BASH_COMMAND' DEBUG  # example
不幸的是,这意味着当我键入以下内容时:

sleep 1; sleep 2; sleep 3
我没有处理包含整行的$BASH_命令,而是在三个不同的陷阱中获得三个睡眠。更糟糕的是:

sleep 1 | sleep 2 | sleep 3
在管道设置时激发所有三个,甚至在sleep 1开始执行之前,输出可能会让您相信sleep 3正在运行

我需要一种从一开始就执行脚本的方法,处理整个命令,我不希望在运行提示符命令时触发脚本,但如果必须,我可以处理它。

此解决方案存在一个主要问题。带有管道的命令|将完成陷阱的执行,但在陷阱期间将进程回退将导致命令的处理冻结-如果不点击^C,您将永远无法得到返回的提示。陷阱完成,但$PROMPT|命令永远不会运行。即使您在后台处理后立即与流程断开连接,此问题仍然存在

这比我想象的要有趣一些:

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

您想在解析和执行行之前执行代码吗?在那一点上你想做什么?我有几件事要用命令行做。我将其打印到状态行,以便在命令运行时xterm的标题更改。它使查找特定的最小化窗口变得更加容易。我还想在状态行中添加一个时钟,以便知道命令运行了多长时间。这比听起来容易。主要的是我希望整个命令都由脚本处理。我能构造的最简单的示例是:trap'echo-en\033]0$BASH_COMMAND\007'DEBUGI想不出任何方法来使用BASH实现这一点,但较新版本可能有一些功能。这在zsh中可能是可能的,因为它在这类领域有点花哨,但我不知道。我正在考虑坚持使用调试陷阱并这样做:当陷阱触发时,它会检查某个文件是否$LOCK?存在,但它不存在,它创建它并执行所有簿记任务从历史记录中获取命令似乎有效。如果$LOCK已存在,则此命令的簿记已由先前的陷阱完成。我所要做的就是在生成提示或用户注销时删除该文件,等等。