mirror of
https://github.com/rcaloras/bash-preexec.git
synced 2026-11-03 14:39:43 -09:00
Merge pull request #180 from Rogach/fix/login-shell-first-preexec
This commit is contained in:
commit
a220343bf2
2 changed files with 95 additions and 23 deletions
|
|
@ -137,19 +137,22 @@ __bp_sanitize_string() {
|
|||
# We specify newline character through the variable `nl' because $'\n'
|
||||
# inside "${var//...}" is treated literally as "\$'\\n'" when `extquote' is
|
||||
# unset (shopt -u extquote). (Note: Bash 5.2's extquote seems to be buggy.)
|
||||
local tmp sp=$' \t' nl=$'\n'
|
||||
local tmp nl=$'\n'
|
||||
while
|
||||
# Quoting parameter expansions $nl in PAT of ${var//PAT/REP} is
|
||||
# Note: Quoting parameter expansions $nl in PAT of ${var//PAT/REP} is
|
||||
# required by shellcheck. On the other hand, we should not quote the
|
||||
# parameter expansions $nl in REP because the quotes will remain in the
|
||||
# replaced result with `shopt -s compat42'.
|
||||
tmp="${sanitized//[";$nl"]*(["$sp"]):*(["$sp"])[";$nl"]/$nl}"
|
||||
# Note: We use ?(+([[:blank:]])) instead of *([[:blank:]]) to work
|
||||
# around a bug of Bash 3.2 that *(...) is not properly processed as
|
||||
# extglob at the beginning of the pattern in ${var//pat/rep}.
|
||||
tmp="${sanitized//?(+([[:blank:]]))[";$nl"]*([[:blank:]]):*([[:blank:]])[";$nl"]*([[:blank:]])/$nl}"
|
||||
[[ "$tmp" != "$sanitized" ]]
|
||||
do
|
||||
sanitized="$tmp"
|
||||
done
|
||||
sanitized="${sanitized#:*(["$sp"])[";$nl"]}"
|
||||
sanitized="${sanitized%[";$nl"]*(["$sp"]):}"
|
||||
sanitized="${sanitized#:*([[:blank:]])[";$nl"]}"
|
||||
sanitized="${sanitized%[";$nl"]*([[:blank:]]):}"
|
||||
__bp_trim_whitespace sanitized "$sanitized"
|
||||
sanitized=${sanitized%;}
|
||||
sanitized=${sanitized#;}
|
||||
|
|
@ -541,14 +544,18 @@ __bp_install_after_session_init() {
|
|||
__bp_require_not_readonly PS0 || return
|
||||
fi
|
||||
|
||||
local sanitized_prompt_command
|
||||
__bp_sanitize_string sanitized_prompt_command "${PROMPT_COMMAND:-}"
|
||||
if [[ -n "$sanitized_prompt_command" ]]; then
|
||||
# shellcheck disable=SC2178 # PROMPT_COMMAND is not an array in bash <= 5.0
|
||||
PROMPT_COMMAND=${sanitized_prompt_command}$'\n'
|
||||
if __bp_use_array_prompt_command; then
|
||||
PROMPT_COMMAND+=("${__bp_install_string}")
|
||||
else
|
||||
local sanitized_prompt_command
|
||||
__bp_sanitize_string sanitized_prompt_command "${PROMPT_COMMAND:-}"
|
||||
if [[ -n "$sanitized_prompt_command" ]]; then
|
||||
# shellcheck disable=SC2178 # PROMPT_COMMAND is not an array in bash <= 5.0
|
||||
PROMPT_COMMAND=${sanitized_prompt_command}$'\n'
|
||||
fi
|
||||
# shellcheck disable=SC2179 # PROMPT_COMMAND is not an array in bash <= 5.0
|
||||
PROMPT_COMMAND+=${__bp_install_string}
|
||||
fi
|
||||
# shellcheck disable=SC2179 # PROMPT_COMMAND is not an array in bash <= 5.0
|
||||
PROMPT_COMMAND+=${__bp_install_string}
|
||||
}
|
||||
|
||||
# Run our install so long as we're not delaying it.
|
||||
|
|
|
|||
|
|
@ -76,13 +76,28 @@ set_exit_code_and_run_precmd() {
|
|||
|
||||
# Assert that before running, the command contains the install string, and
|
||||
# afterwards it does not
|
||||
[[ "$PROMPT_COMMAND" == *"$__bp_install_string"* ]] || return 1
|
||||
[[ "$(join_PROMPT_COMMAND)" == *"$__bp_install_string"* ]] || return 1
|
||||
|
||||
eval_PROMPT_COMMAND
|
||||
|
||||
[[ "$PROMPT_COMMAND" != *"$__bp_install_string"* ]] || return 1
|
||||
[[ "$(join_PROMPT_COMMAND)" != *"$__bp_install_string"* ]] || return 1
|
||||
}
|
||||
|
||||
@test "__bp_install should remove trap logic and itself from modified PROMPT_COMMAND" {
|
||||
PROMPT_COMMAND=()
|
||||
__bp_install_after_session_init
|
||||
PROMPT_COMMAND="$PROMPT_COMMAND; true"
|
||||
|
||||
# Assert that before running, the command contains the install string, and
|
||||
# afterwards it does not
|
||||
[[ "$(join_PROMPT_COMMAND)" == *"$__bp_install_string"* ]] || return 1
|
||||
|
||||
eval_PROMPT_COMMAND
|
||||
|
||||
[[ "$(join_PROMPT_COMMAND)" != *"$__bp_install_string"* ]] || return 1
|
||||
}
|
||||
|
||||
|
||||
@test "__bp_install should preserve an existing DEBUG trap" {
|
||||
trap_invoked_count=0
|
||||
foo() { (( trap_invoked_count += 1 )); }
|
||||
|
|
@ -236,7 +251,7 @@ set_exit_code_and_run_precmd() {
|
|||
[ "$output" == "echo USER9" ]
|
||||
|
||||
__bp_sanitize_string output $'echo USER10 ; :\n: ; echo USER11'
|
||||
expected_result=$'echo USER10 \n echo USER11'
|
||||
expected_result=$'echo USER10\necho USER11'
|
||||
[ "$output" == "$expected_result" ]
|
||||
}
|
||||
|
||||
|
|
@ -250,7 +265,9 @@ set_exit_code_and_run_precmd() {
|
|||
@test "Appending or prepending to PROMPT_COMMAND should work after bp_install_after_session_init" {
|
||||
__bp_install_after_session_init
|
||||
nl=$'\n'
|
||||
PROMPT_COMMAND="$PROMPT_COMMAND; true"
|
||||
# On Bash 5.1+ we append to the array properly,
|
||||
# so first element of PROMPT_COMMAND may still be empty.
|
||||
PROMPT_COMMAND="${PROMPT_COMMAND:+$PROMPT_COMMAND; }true"
|
||||
PROMPT_COMMAND="$PROMPT_COMMAND $nl true"
|
||||
PROMPT_COMMAND="$PROMPT_COMMAND; true"
|
||||
PROMPT_COMMAND="true; $PROMPT_COMMAND"
|
||||
|
|
@ -260,6 +277,24 @@ set_exit_code_and_run_precmd() {
|
|||
eval_PROMPT_COMMAND
|
||||
}
|
||||
|
||||
@test "Appending or prepending to PROMPT_COMMAND array should work after bp_install_after_session_init" {
|
||||
if __bp_use_array_prompt_command; then
|
||||
PROMPT_COMMAND=()
|
||||
__bp_install_after_session_init
|
||||
nl=$'\n'
|
||||
PROMPT_COMMAND=("${PROMPT_COMMAND[@]}" "true")
|
||||
PROMPT_COMMAND=("${PROMPT_COMMAND[@]}" "$nl true")
|
||||
PROMPT_COMMAND=("${PROMPT_COMMAND[@]}" "true")
|
||||
PROMPT_COMMAND=("true" "${PROMPT_COMMAND[@]}")
|
||||
PROMPT_COMMAND=("true" "${PROMPT_COMMAND[@]}")
|
||||
PROMPT_COMMAND=("true" "${PROMPT_COMMAND[@]}")
|
||||
PROMPT_COMMAND=("true $nl" "${PROMPT_COMMAND[@]}")
|
||||
eval_PROMPT_COMMAND
|
||||
else
|
||||
skip
|
||||
fi
|
||||
}
|
||||
|
||||
# Case where a user is appending or prepending to PROMPT_COMMAND.
|
||||
# This can happen after 'source bash-preexec.sh' e.g.
|
||||
# source bash-preexec.sh; PROMPT_COMMAND="$PROMPT_COMMAND; other_prompt_command_hook"
|
||||
|
|
@ -267,23 +302,27 @@ set_exit_code_and_run_precmd() {
|
|||
PROMPT_COMMAND="echo before"
|
||||
PROMPT_COMMAND="$PROMPT_COMMAND; echo before2"
|
||||
__bp_install_after_session_init
|
||||
PROMPT_COMMAND="$PROMPT_COMMAND"$'\n echo after'
|
||||
PROMPT_COMMAND="$PROMPT_COMMAND"$'\necho after'
|
||||
PROMPT_COMMAND="echo after2; $PROMPT_COMMAND;"
|
||||
|
||||
eval_PROMPT_COMMAND
|
||||
|
||||
expected_result=$'__bp_precmd_invoke_cmd "$_"\necho after2; echo before; echo before2\n echo after\n__bp_interactive_mode'
|
||||
expected_result=$'__bp_precmd_invoke_cmd "$_"\necho after2; echo before; echo before2\necho after\n__bp_interactive_mode'
|
||||
[ "$(join_PROMPT_COMMAND)" == "$expected_result" ]
|
||||
}
|
||||
|
||||
@test "Adding to PROMPT_COMMAND after with semicolon" {
|
||||
PROMPT_COMMAND="echo before"
|
||||
__bp_install_after_session_init
|
||||
PROMPT_COMMAND="$PROMPT_COMMAND; echo after"
|
||||
if __bp_use_array_prompt_command; then
|
||||
PROMPT_COMMAND[${#PROMPT_COMMAND[@]}-1]+='; echo after'
|
||||
else
|
||||
PROMPT_COMMAND+='; echo after'
|
||||
fi
|
||||
|
||||
eval_PROMPT_COMMAND
|
||||
|
||||
expected_result=$'__bp_precmd_invoke_cmd "$_"\necho before\n echo after\n__bp_interactive_mode'
|
||||
expected_result=$'__bp_precmd_invoke_cmd "$_"\necho before\necho after\n__bp_interactive_mode'
|
||||
[ "$(join_PROMPT_COMMAND)" == "$expected_result" ]
|
||||
}
|
||||
|
||||
|
|
@ -296,12 +335,38 @@ set_exit_code_and_run_precmd() {
|
|||
|
||||
precmd() { echo "inside precmd"; }
|
||||
run eval_PROMPT_COMMAND
|
||||
[ "${#lines[@]}" == '5' ]
|
||||
[ "${lines[0]}" == "after2" ]
|
||||
[ "${lines[1]}" == "before" ]
|
||||
[ "${lines[2]}" == "before2" ]
|
||||
[ "${lines[3]}" == "inside precmd" ]
|
||||
[ "${lines[4]}" == "after" ]
|
||||
[ "${#lines[@]}" == '5' ]
|
||||
if __bp_use_array_prompt_command; then
|
||||
[ "${lines[3]}" == "after" ]
|
||||
[ "${lines[4]}" == "inside precmd" ]
|
||||
else
|
||||
[ "${lines[3]}" == "inside precmd" ]
|
||||
[ "${lines[4]}" == "after" ]
|
||||
fi
|
||||
}
|
||||
|
||||
@test "during install PROMPT_COMMAND and precmd functions should be executed each once (Bash 5.1+ PROMPT_COMMAND array)" {
|
||||
if __bp_use_array_prompt_command; then
|
||||
PROMPT_COMMAND=("echo before")
|
||||
PROMPT_COMMAND=("${PROMPT_COMMAND[@]}" "echo before2")
|
||||
__bp_install_after_session_init
|
||||
PROMPT_COMMAND=("${PROMPT_COMMAND[@]}" "echo after")
|
||||
PROMPT_COMMAND=("echo after2" "${PROMPT_COMMAND[@]}")
|
||||
|
||||
precmd() { echo "inside precmd"; }
|
||||
run eval_PROMPT_COMMAND
|
||||
[ "${#lines[@]}" == '5' ]
|
||||
[ "${lines[0]}" == "after2" ]
|
||||
[ "${lines[1]}" == "before" ]
|
||||
[ "${lines[2]}" == "before2" ]
|
||||
[ "${lines[3]}" == "inside precmd" ]
|
||||
[ "${lines[4]}" == "after" ]
|
||||
else
|
||||
skip
|
||||
fi
|
||||
}
|
||||
|
||||
@test "No functions defined for preexec should simply return" {
|
||||
|
|
|
|||
Loading…
Reference in a new issue