Use preexec() to evaluate entered command

*爱你&永不变心* 提交于 2019-12-07 11:14:17

问题


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 bitch

And then I want preexec to see I wrote bitch at the end and replace it with

sudo ls -l /root

I think something like

preexec() {
    if [[ $CURRENT_LINE =~ bitch$ ]]; then
        $CURRENT_LINE="sudo ${CURRENT_LINE% bitch}"
    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 bitch 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 bitch 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.


回答1:


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" == *" bitch" ]]; then
    BUFFER="sudo ${BUFFER% bitch}"
  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



来源:https://stackoverflow.com/questions/28099966/use-preexec-to-evaluate-entered-command

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!