Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

no preexec call for subshells #164

Open
dseomn opened this issue Jan 9, 2025 · 3 comments
Open

no preexec call for subshells #164

dseomn opened this issue Jan 9, 2025 · 3 comments

Comments

@dseomn
Copy link
Contributor

dseomn commented Jan 9, 2025

Similar to #6, I'm not seeing preexec calls for subshells. That was supposed to be fixed in #22 though, right?

* dseomn@solaria:~$ preexec() { echo "command: $1"; }
* dseomn@solaria:~$ true
command: true
* dseomn@solaria:~$ (true)
* dseomn@solaria:~$
@akinomyoga
Copy link
Contributor

akinomyoga commented Jan 9, 2025

That was supposed to be fixed in #22 though, right?

It caused the problem reported in #25, so it was turned off by default in commit 6db22a5. Bash >= 5.0 are free from the reported problem, so if you want to enable it, you can set a non-empty value to a global shell variable __bp_enable_subshells.

However, __bp_enable_subshells=1 has another issue. See the following examples:

$ (echo 1; echo 2); echo 3; echo 4
1
2
preexec        <-- We wanted this before "1"
3
4
precmd
$ __bp_enable_subshells=1 bash
$ (echo 1; echo 2); echo 3; echo 4
preexec        <-- Expected. Now, we have preexec at the beginning
1
preexec        <-- We do not want this
2
preexec        <-- We do not want this
3
4
precmd
$

"PS0 & signal" or "PS0 & funsub" discussed in #28 should provide a better solution.

@dseomn
Copy link
Contributor Author

dseomn commented Jan 9, 2025

Could the multiple preexec issue be solved in bash 5.0, 5.1, and 5.2 with a new internal variable to suppress it? Something like this before calling preexec:

if [[ "$__bp_done_preexec" = "1" ]]; then
  return
fi
__bp_done_preexec=1
...  # call preexec

And in precmd:

__bp_done_preexec=0

@akinomyoga
Copy link
Contributor

Could the multiple preexec issue be solved in bash 5.0, 5.1, and 5.2 with a new internal variable to suppress it?

We are already doing this with the variable __bp_preexec_interactive_mode (__bp_preexec_interactive_mode=on corresponds to your __bp_done_preexec=0 and __bp_preexec_interactive_mode="" corresponds to your __bp_done_preexec=1). However, it is intentionally turned off inside subshells for some historical reasons:

else
# If we're in a subshell, then the prompt won't be re-displayed to put
# us back into interactive mode, so let's not set the variable back.
# In other words, if you have a subshell like
# (sleep 1; sleep 2)
# You want to see the 'sleep 2' as a set_command_title as well.
if [[ 0 -eq "${BASH_SUBSHELL:-}" ]]; then
__bp_preexec_interactive_mode=""
fi

The second preexec (before echo 2) may be suppressed by removing the requirement [[ 0 -eq "${BASH_SUBSHELL:-}" ]]. I thought there was a discussion about this, but I do not find it now. Maybe my memory is incorrect.

The third preexec (before echo 3) cannot be fixed by the internal-variable approach because the changes to the variable in subshell is invisible from the parent shell.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants