I want to use preexec() to modify certain commands before they are run but I need to be able to evaluate the current entered command. Is there a variable that contains the entire command before it is executed? I know !!
is the last command but I need the current line before it's saved to history.
An example of what I want to do would probably help
ls -l /root please
And then I want preexec to see I wrote "please" at the end and replace it with
sudo ls -l /root
I think something like
preexec() {
if [[ $CURRENT_LINE =~ please$ ]]; then
$CURRENT_LINE="sudo ${CURRENT_LINE% please}"
fi
Would work but I can't find a variable in zsh that gives me the correct $CURRENT_LINE
For bonus points I also want to be able to enter please
on a line by itself and have it run sudo !!
but I could probably do that with some form of alias.
I think it might be better to make a please
function that I can pipe a command to but I don't think that'll work as well because the command will run and fail (before piping) before it is run again with sudo.
As far as I know that the preexec
is not for the right place to modify the command to be executed though. We can not change the commands to be executed from inside of the preexec
function…
Although the actual command to be executed are passed as $1
, $2
and $3
.
preexec
Executed just after a command has been read and is about to be executed. If the history mechanism is active (and the line was not discarded from the history buffer), the string that the user typed is passed as the first argument, otherwise it is an empty string. The actual command that will be executed (including expanded aliases) is passed in two different forms: the second argument is a single-line, size-limited version of the command (with things like function bodies elided); the third argument contains the full text that is being executed.
--
zshmisc(1)
9.3.1 Hook Functions
For example:
alias ls='ls -sF --color=auto'
preexec () {
print ">>>preexec<<<"
print -l ${(qqq)@}
}
If I have above in ~/.zshrc
then I will get follows:
% echo test preexec<Esc-Return>
ls<Return>
;# outputs below
>>>preexec<<<
"echo test preexec
ls"
"echo test preexec; ls -sF --color=auto"
"echo test preexec
ls -sF --color=auto"
test preexec
total 1692
...
You could add your own zle widget functions to the zsh line editor for manipulating the line editor buffer. (zshzle(1)
)
You could add the zle widget function to change the behavior for hitting Enter.
my-accept-line () {
if [[ "$BUFFER" == *" please" ]]; then
BUFFER="sudo ${BUFFER% please}"
fi
zle .accept-line
}
zle -N accept-line my-accept-line
The above snippets changes the functionality for accept-line
from the built-in behavior to my-accept-line
defined here.
Adding the abbreviations also could help which is described below:
Cloning vim's abbreviation feature
-- “examples:zleiab [ZshWiki]” - http://zshwiki.org/home/examples/zleiab
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With