2

I have a complicated mechanism built into my bash environment that requires the execution of a couple scripts when the prompt is generated, but also when the user hits enter to begin processing a command. I'll give an oversimplified description:

The debug trap does this in a fairly limited way: it fires every time a statement is executed.

trap 'echo $BASH_COMMAND' DEBUG  # example only

Unfortunately, this means that when I type this:

sleep 1; sleep 2; sleep 3

rather than processing a $BASH_COMMAND that contains the entire line, I get the three sleeps in three different traps. Worse yet:

sleep 1 | sleep 2 | sleep 3

fires all three as the pipe is set up - before sleep 1 even starts executing, the output might lead you to believe that sleep 3 is running.

I need a way to execute a script right at the beginning, processing the entire command, and I'd rather it not fire when the prompt command is run, but I can deal with that if I must.

0

1 Answer 1

3

Not very pretty, but if you really need this you could use PROMPT_COMMAND in addition to the debug trap to get rid of the extra calls:

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'

Now:

$ echo 1 ; echo 2 | cat
hook
1
2

We still don't have access to the whole input line however: $BASH_COMMAND is just echo 1.


Another idea inspired by this article is to use readline bindings to get access to the whole line:

$ bind -x '"\C-o":hook'
$ hook(){ echo "hook: $READLINE_LINE";  }
$ bind 'RETURN: "\C-o\n"'

Now it works:

hook: echo 1; echo 2
$ echo 1; echo 2
1
2

One thing to keep in mind though: for multi-line input it'll get invoked once for each line which may not be what you want (could use a combination of both approaches then).

1
  • I eventually wound up calling history from the trap handler and grabbing the most recent command line. Along the way, I learned to NEVER background a process in a trap handler. Even if you disown the process, the trap will not return until the subprocess has terminated. Dec 10, 2014 at 0:30

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .