-
Notifications
You must be signed in to change notification settings - Fork 95
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
bash 4.4: using $PS0 #28
Comments
@d630 thanks for opening! Was thinking about this when I saw http://superuser.com/a/1052132 a little while back. Probably makes sense to add some version detection and then hook into the appropriate interface. |
Ok, I have updated my repo to use PS0 only. Note:
|
@d630 awesome. Giving it a look. Could you elaborate on your second bullet?
Do you mean you can't alter PS0 itself while it's invoked? |
That's possible: foo () { printf '%s\n\r' FOO; }
PSO='\h\n\T$(foo)'
PS0='$(printf "%s\n%s\n%s\n\r" \h \T FOO)' But not: foo () { printf '%s\n%s\n%s\n\r' \\h \\T FOO; }
PS0='$(foo)'
PSO='$(PS0=FOO)' |
Also possible: foo () { printf '%s\n\r' "${paa[u]}" "${paa[V]}" "${pa[0]}" "$PROMPT_w" "$1"; }
PS0='$(declare -A paa=([u]="\u" [V]="\V"); pa=("\w") ;PROMPT_w="\w" foo "\H")' |
I would go with something like: foo ()
{
for i in "${!BPX_PROMPT[@]}"
do
printf '%s -> %s\n\r' "$i" "${BPX_PROMPT[$i]}"
done
}
PS0='$(
builtin unset -v BPX_PROMPT;
builtin unset -f typeset;
builtin unalias typeset 2>/dev/null;
typeset -A BPX_PROMPT=(
[h]="\h"
[H]="\H"
[j]="\j"
[l]="\l"
[s]="\s"
[u]="\u"
[v]="\v"
[V]="\V"
[w]="\w"
[W]="\W"
[\\!]="\!"
[#]="\#"
[\$]="\$"
[d]="\d"
[t]="\t"
[T]="\T"
[\\@]="\@"
[A]="\A"
[unixtime]="\D{%s}"
);
foo
)' What is then:
edit: In bash 4.4 we can use "parameter transformation". Most of these prompt strings can then be expanded within the command substitution in PS0. v='\T \W \#'
echo "${v@P}"
> 08:09:59 ~ 70 |
I doubt However, command substitutions run in their own subshell, therefore no variables in the original shell can be modified from this context. This would be different behavior than running commands in the trap handler as it is now, from where the state of the shell can be modified. Within PS0, commands can only print data for stdout, or at most write to file descriptors. |
Thanks for pointing it out again. I think, it's obviously a preprompt, not preexecution thing! PS0 will be set before the hole command line is beeing executed, which may also be a command list; it's expanded after the list from the line has been read. That is, you have only got access to the hole line (when you have enabled the command history feature). The DEBUG trap applies to every command pipeline from the list, just before their executions. Even though you might have a similar thing like PROMPT_COMMAND for it, it wouldn't be useful without having access to the commands from the list, which will be executing. So, you also need a second thing like BASH_COMMAND, that indicates, which command is beeing read, right?! Unfortunately yes, PS0 cannot replace the DEBUG trap. |
Ahh bummer, was really hoping to move to something more reliable than the DEBUG trap due to #25 Hopes dashed for now :/ |
I have been thinking about the preexec hook for quite a while (again). Maybe I am wrong, but in the end I found, that PS0 cannot replace the DEBUG trap as key to emulate the zsh prexec itself, (since you need command substitution for functions in it) but with the help of Readline key sequences you can! I have just now updated my bpx repo. Check it out and let me know, what do you think! |
Haven't checked further but one idea could be to send a signal from the PS0-subshell. test.sh:
Terminal session:
In the bash manual I don't see a dealbreaker:
|
The next version of Bash, 5.3 (still under development), supports function substitutions (and value substitutions) of the form I guess |
ah, interesting. similiar to |
Right. Chet indeed mentioned mksh: https://lists.gnu.org/archive/html/bug-bash/2023-05/msg00078.html By the way, I wrote above that a value substitution can be used, but I noticed that the shell variable PS0+='${ __bp_preexec_invoke_from_ps0 >/dev/tty; }' One possible caveat of this approach is that |
A possible caution: I came across this suggestion and implemented it in my own PROMPT_COMMAND handling (rather than integrating bash-preexec into my own overly complex prompt setup) sometime earlier than 2022, and it only just occurred to me that it was behind some annoying behaviour I've been experiencing: debian stable bash: 5.2.15(1)-release
precmd_hook may have had some backgrounded functions within it, or may have called scripts that backgrounded things themselves. disown or double forking was appropriately used. I'm pretty sure the same behaviour was exhibited even if there was nothing ever background invoked. But job1 & job2 & job3 & would result in them getting job numbers %3, %6, %9, and
This was perhaps because the signal handler had executed something in the context of a (backgrounded?) subshell even though it was behaviour as if it was entirely operating within the context of the parent shell. I never solved the issue and ported my bash pre- and post- exec stuff over to using bash-preexec instead, problem free (except for #25). I'd just suggest testing this before going to any effort to porting over to a signal handler and PS0 triggering, as neat as the idea is. |
Could you provide a concrete setup that reproduces that annoying behavior? I guess this is one of the behaviors that will be fixed in the next release of Bash 5.3. See the following example. With Bash 5.2, $ bash-5.2 --norc
$ trap 'for i in 1 2 3; do /bin/true; /bin/true; sleep 1 & done; jobs' RTMIN
$ kill -RTMIN $$
[1] Done kill -RTMIN $$
[2] Done kill -RTMIN $$
[3] Running kill -RTMIN $$ &
[4] Done kill -RTMIN $$
[5] Done kill -RTMIN $$
[6]- Running kill -RTMIN $$ &
[7] Done kill -RTMIN $$
[8] Done kill -RTMIN $$
[9]+ Running kill -RTMIN $$ &
$
[3] Done kill -RTMIN $$
[6]- Done kill -RTMIN $$
[9]+ Done kill -RTMIN $$
$ This behavior will be fixed in Bash 5.3 as follows: $ bash-dev --norc
$ trap 'for i in 1 2 3; do /bin/true; /bin/true; sleep 1 & done; jobs' RTMIN
$ kill -RTMIN $$
[1] Running kill -RTMIN $$ &
[2]- Running kill -RTMIN $$ &
[3]+ Running kill -RTMIN $$ &
$
[1] Done kill -RTMIN $$
[2]- Done kill -RTMIN $$
[3]+ Done kill -RTMIN $$
$ I guess this would be related to what you've described, but I'm not totally sure.
The Bash behavior was based on the Bash maintainer's interpretation of the POSIX wording. The foreground jobs also get its job numbers, but the foreground ones are usually immediately removed from the job table at its termination. However, inside trap handlers, the foreground jobs have never been removed from the job table until the trap handler completes. I first reported this to Bash with patches in 2022 [1], but it was only partially fixed [2]. I asked the reasoning in [3], but Chet, the Bash maintainer, seemed to have believed that the POSIX standard requires this. I gave up then. This year, I reported another case [4], and Chet still seemed to think the POSIX required this strange behavior. Then, POSIX people chimed in, and this triggered a big discussion about the POSIX interpretation [4,5], and the behavior was finally fixed.
|
OK, seem to have whittled it down to something pretty "minimal" (ok, smaller than the 30K of files that makes up my .bashrc.d/*). Doesn't exactly reproduce what I was seeing in my full setup, but seems pretty close:
Followed by for actual testing:
etc You can try with ~/bin/background_processing_job as a shell script (with or without backgrounding, with or without double forking), or as a shell function (ditto), so slightly worse scenario than yours above. I have not tested bash 5.3 |
The provided setup still seems redundant. The minimal reproducer is this: $ trap '/bin/true' RTMIN; PS0='$(kill -RTMIN $$)'
$ /bin/true
$ jobs
[1] Done /bin/true
$ /bin/true &
[2] 40067
$ jobs
[2]+ Done /bin/true
[3] Done /bin/true I confirmed that this is fixed in Bash 5.3-beta. |
As far I can see, we may avoid the DEBUG trap in version 4.4:
PS0 is expanded before DEBUG
The text was updated successfully, but these errors were encountered: