Comments (14)
I doubt PS0
can ever be used for an implementation of preexec()
. PS0
is treated as a prompt string, not a list of commands. The only way to inject commands is by substitution with $()
.
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.
from bash-preexec.
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:
! -> 1445
# -> 14
$ -> $
unixtime -> 1475483154
@ -> 09:25 AM
A -> 09:25
H -> ICH3
T -> 09:25:54
V -> 4.4.0
W -> ~
d -> Mon Oct 03
h -> ICH3
j -> 0
l -> 0
s -> bash
t -> 09:25:54
u -> user1
v -> 4.4
w -> ~
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
from bash-preexec.
@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.
from bash-preexec.
Ok, I have updated my repo to use PS0 only.
Note:
PSO is meant to be expanded; there is no PROMPT_COMMAND like thing for it. So we have to write something like PSO='$(preexec)'
. Then there are the following problems:
- BASH_COMMAND is unusable;
- you can not set any further strings in PSO via preexec (you can set PS1 in precmd);
- the command substitution removes the trailing newline.
from bash-preexec.
@d630 awesome. Giving it a look.
Could you elaborate on your second bullet?
- you can not set any further strings in PSO via preexec (you can set PS1 in precmd);
Do you mean you can't alter PS0 itself while it's invoked?
from bash-preexec.
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)'
from bash-preexec.
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")'
from bash-preexec.
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.
from bash-preexec.
Ahh bummer, was really hoping to move to something more reliable than the DEBUG trap due to #25 Hopes dashed for now :/
from bash-preexec.
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!
from bash-preexec.
Haven't checked further but one idea could be to send a signal from the PS0-subshell.
test.sh:
counter=0
trap_handler(){
counter=$((counter+1))
echo "hi from trap_handler: $counter: $(history 1)" >&2
}
trap trap_handler SIGRTMIN
PS0='$(echo "sending signal... "; kill -SIGRTMIN $$; )'
Terminal session:
$ source test.sh
$ echo ok
sending signal... hi from trap_handler: 1: 4118 echo ok
ok
$ echo two
sending signal... hi from trap_handler: 2: 4119 echo two
two
$
In the bash manual I don't see a dealbreaker:
If Bash is waiting for a command to complete and receives a signal for which a trap has been set, the trap will not be executed until the command completes. When Bash is waiting for an asynchronous command via the wait builtin, the reception of a signal for which a trap has been set will cause the wait builtin to return immediately with an exit status greater than 128, immediately after which the trap is executed.
from bash-preexec.
The next version of Bash, 5.3 (still under development), supports function substitutions (and value substitutions) of the form ${ command; }
(and ${| command; }
), which are variants of the command substitution but executed in the main shell.
I guess PS0
can be combined to the value substitutions ${| command; }
to provide a more robust preexec
in Bash >= 5.3.
from bash-preexec.
ah, interesting. similiar to funsubs
and valsubs
in mksh, right?
from bash-preexec.
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 REPLY
is rewritten and there is no way to prevent it. I now think function substitution should be used. Something like this:
PS0+='${ __bp_preexec_invoke_from_ps0 >/dev/tty; }'
One possible caveat of this approach is that preexec
is executed before the PS0
content is output to the terminal, though I'm not sure if that is really an issue.
from bash-preexec.
Related Issues (20)
- Preexec is called when exiting bash with Ctrl-D HOT 2
- Return immediately when running in Zsh HOT 3
- [Bug] HISTCONTROL ignore* setting should be respected HOT 7
- `__bp_preexec_invoke_exec "$_"` printed when running multiple commads
- Tests fail with bats 1.5.0 HOT 7
- official way to detect whether bash-preexec is loaded HOT 2
- Line number exit outpu command ? HOT 1
- Bash 5.1 supports making PROMPT_COMMAND an array HOT 5
- ShellCheck highlights several issues with the file - Shellcheck could be disabled, or issues resolved HOT 2
- post_cmd functionality addition HOT 2
- Functions called in opposite order in midnight commander subshell HOT 2
- Some tests fail with bats 1.9 HOT 6
- preexec() does not work where as precmd() is working as intended. HOT 1
- Library Authors documentation can still lead to issues HOT 2
- preexec $1 is missing some commands HOT 1
- detailed bash log with preexec and precmd HOT 2
- Not working on Windows using Bash in MSYS2 HOT 7
- preexec doesn't work for no-op command `:`
- `bash-preexec` will cause `hishtory` to be particularly time-consuming for commands including pipeline.
- New release when?
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from bash-preexec.