Skip to content

Commit

Permalink
Update bash-preexec.sh
Browse files Browse the repository at this point in the history
- Avoids infinite recursion with things like export PROMPT_COMMAND="history -a; $PROMPT_COMMAND"
- Preserve trap DEBUG again: revert rcaloras#60
  • Loading branch information
lguelorget committed Oct 24, 2017
1 parent b34449e commit 00add19
Showing 1 changed file with 17 additions and 4 deletions.
21 changes: 17 additions & 4 deletions bash-preexec.sh
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ __bp_imported="defined"
__bp_last_ret_value="$?"
__bp_last_argument_prev_command="$_"

__bp_inside_precmd=0
__bp_inside_preexec=0

# Remove ignorespace and or replace ignoreboth from HISTCONTROL
# so we can accurately invoke preexec with a command from our
# history even if it starts with a space.
Expand Down Expand Up @@ -83,6 +86,13 @@ __bp_interactive_mode() {
# This function is installed as part of the PROMPT_COMMAND.
# It will invoke any functions defined in the precmd_functions array.
__bp_precmd_invoke_cmd() {
# Don't invoke precmds if we are inside an execution of an "original
# prompt command" by another precmd execution loop. This avoids infinite
# recursion.
if (( __bp_inside_precmd > 0 )); then
return
fi
local __bp_inside_precmd=1

# Save the returned value from our last command
__bp_last_ret_value="$?"
Expand Down Expand Up @@ -137,6 +147,12 @@ __bp_preexec_invoke_exec() {
# https://stackoverflow.com/questions/40944532/bash-preserve-in-a-debug-trap#40944702
__bp_last_argument_prev_command="$1"

# Don't invoke preexecs if we are inside of another preexec.
if (( __bp_inside_preexec > 0 )); then
return;
fi
local __bp_inside_preexec=1

# Checks if the file descriptor is not standard out (i.e. '1')
# __bp_delay_install checks if we're in test. Needed for bats to run.
# Prevents preexec from being invoked for functions in PS1
Expand Down Expand Up @@ -277,15 +293,12 @@ __bp_install_after_session_init() {
precmd_functions+=(__bp_original_prompt_command)
fi

# Save anything already defined in our trap
__bp_trap_string="$(trap -p DEBUG)"

# Installation is finalized in PROMPT_COMMAND, which allows us to override the DEBUG
# trap. __bp_install sets PROMPT_COMMAND to its final value, so these are only
# invoked once.
# It's necessary to clear any existing DEBUG trap in order to set it from the install function.
# Using \n as it's the most universal delimiter of bash commands
PROMPT_COMMAND=$'\ntrap DEBUG\n__bp_install\n'
PROMPT_COMMAND=$'\n__bp_trap_string="$(trap -p DEBUG)"\n trap DEBUG\n __bp_install\n'
}

# Run our install so long as we're not delaying it.
Expand Down

0 comments on commit 00add19

Please sign in to comment.