Skip to content

Commit 0faeced

Browse files
committed
Accomodate user insistance on HISTCONTROL
If the user still sets `$HISTCONTROL` incompatibly anyway (`ignorespace`), then gracefully fall back to a less-ideal but not-incorrect `$BASH_COMMAND`. Alsö, adopt a modification of @cornfeedhobo's suggestion that doesn't require Bash v5.
1 parent f4bf349 commit 0faeced

File tree

2 files changed

+11
-18
lines changed

2 files changed

+11
-18
lines changed

README.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,6 @@ This is disabled by default due to buggy situations related to to `functrace` an
9797

9898
In order to be able to provide the last command text to the `preexec` hook, this script will remove `ignorespace` and/or will replace `ignoreboth` with `ignoredups` in your `HISTCONTROL` variable. It will remember if `HISTCONTROL` has been modified and will remove the last command from the history "manually", after reading the last command from the history list. This may cause issues when you have scripts that rely on the literal value of `HISTCONTROL` or manipulate history in their own ways.
9999

100-
Unfortunately, this only works with Bash 5.0 and above. In older version of Bash, `ignorespace` and `ignoreboth` will be just silently ignored.
101-
102100
## Tests
103101
You can run tests using [Bats](https://github.com/bats-core/bats-core).
104102
```bash

bash-preexec.sh

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ __bp_require_not_readonly() {
6565
local var
6666
for var; do
6767
if ! ( unset "$var" 2> /dev/null ); then
68-
echo "bash-preexec requires write access to ${var}" >&2
68+
echo "${BASH_SOURCE##*/} requires write access to ${var}" >&2
6969
return 1
7070
fi
7171
done
@@ -91,7 +91,7 @@ __bp_adjust_histcontrol() {
9191
histcontrol="${histcontrol//ignoreboth}"
9292
histcontrol="ignoredups${histcontrol:+:}${histcontrol}"
9393
fi;
94-
export HISTCONTROL="$histcontrol"
94+
HISTCONTROL="$histcontrol"
9595
}
9696

9797
# This variable describes whether we are currently in "interactive mode";
@@ -214,8 +214,7 @@ __bp_preexec_invoke_exec() {
214214
return
215215
fi
216216
if [[ -z "${__bp_preexec_interactive_mode:-}" ]]; then
217-
# We're doing something related to displaying the prompt. Let the
218-
# prompt set the title instead of me.
217+
# We're doing something related to displaying the prompt.
219218
return
220219
else
221220
# If we're in a subshell, then the prompt won't be re-displayed to put
@@ -236,10 +235,12 @@ __bp_preexec_invoke_exec() {
236235
fi
237236

238237
local this_command
239-
this_command=$(
240-
export LC_ALL=C
241-
HISTTIMEFORMAT= builtin history 1 | sed '1 s/^ *[0-9][0-9]*[* ] //'
242-
)
238+
if [[ "$HISTCONTROL" == *ignore+(both|space)* ]]
239+
then
240+
this_command="${BASH_COMMAND:-}"
241+
else
242+
this_command="$( HISTTIMEFORMAT= builtin history 1 | sed '1 s/^ *[0-9][0-9]*[* ] //' )"
243+
fi
243244

244245
# Sanity check to make sure we have something to invoke our function with.
245246
if [[ -z "$this_command" ]]; then
@@ -249,13 +250,8 @@ __bp_preexec_invoke_exec() {
249250
# If we have remove "ignorespace" or "ignoreboth" from HISTCONTROL during
250251
# setup, we need to remove commands that start with a space from the
251252
# history ourselves.
252-
253-
# Unfortunately, we need bash 5.0 or above, as "history -d" does not
254-
# support negative indices in earlier versions and HISTCMD seems to be
255-
# unreliable. At least in the unit tests HISTCMD is just set to 1, after
256-
# any number of "history -s" calls.
257-
if [[ "${BASH_VERSINFO:-0}" -ge 5 && -n "$__bp_ignorespace" && "$this_command" == " "* ]]; then
258-
builtin history -d -1
253+
if [[ -n "${__bp_ignorespace:-}" && "$this_command" == " "* ]]; then
254+
history -d "$(HISTTIMEFORMAT= builtin history 1 | sed -r '1 s/^ *([0-9][0-9]*)[* ] .*$/\1/')"
259255
fi
260256

261257
# Invoke every function defined in our function array.
@@ -265,7 +261,6 @@ __bp_preexec_invoke_exec() {
265261
for preexec_function in "${preexec_functions[@]:-}"; do
266262

267263
# Only execute each function if it actually exists.
268-
# Test existence of function with: declare -[fF]
269264
if type -t "$preexec_function" 1>/dev/null; then
270265
__bp_set_ret_value ${__bp_last_ret_value:-}
271266
# Quote our function invocation to prevent issues with IFS

0 commit comments

Comments
 (0)