4

I noticed I like to execute certain actions in a specific order.

A hook, as I see it, is basically "do something after event", where event, could be any command with parameters, such as git clone, git submodule add, cd, rm or any other.

I'd like to say, "if git add, do git status". For example, I always: git add X; git status, and cd X; ls -la, and I can think of many more combinations like that, that I'd like to automate within my workflow.

There are 3 reasons why aliases \ functions won't easily work here:

  1. The main reason I don't think it can be easily done is that I have multiple function definitions and haven't found a way to override existing functions while still being able to use them.

I'll illustrate what I mean with an example: I use some zsh scripts by Nathan Broadbent called SCM Breeze - the scripts add a git() function that does things.

Suppose now I want to automate my workflow, and make it so that after every git clone, there is a cd to the directory made by the previous command (Here's how to do that). To do that, I'll use a git() function, right?

That function would override the SCM Breeze command, and I won't be able to use SCM Breeze.

  1. Aliases require me to remember things. I want this to happen automatically.
  2. It's not easy to maintain - I tried manually overriding each command, but changing things is really cumbersome, and I don't see myself doing it for every combination I can think of because of the complexity.

I use ZSH with OhMyZsh, if that helps.

Right now, I'm doing it with bash scripts (aliases and functions), but it feels as if I'm doing work very likely done by somebody else by now. Anyone familier with a project that does that? help facilitate "hooks" in a tidy fashion?

2
  • 2
    What kind of "hook" are you thinking of? Isn't an alias or maybe a shell function exactly what you want?
    – michas
    Nov 26, 2013 at 7:52
  • See the "DEBUG" trap Nov 26, 2013 at 12:36

2 Answers 2

6

Things that may help you:

The preexec hook function is called before every command line is executed (not before every command).

preexec() echo will execute: $1

precmd before each prompt.

precmd() echo executed: $history[$[HISTCMD-1]]

You can extend a function like this:

functions[git]='
  (){ '$functions[git]'; } "$@"; local myret=$?
  do-extra-stuff
  return $myret'

Or:

functions[git-old]=$functions[git]
git() {
  git-old "$@"
  local myret=$?
  do-extra-stuff || return $myret
}

The DEBUG trap is executed after each command:

trap 'echo $ZSH_DEBUG_CMD returned with $?' DEBUG

You can redefine the accept-line widget (mapped to Enter) to do stuff in there:

accept-line() {
  zle -R "going to run: $BUFFER"
  sleep 1
  zle .$WIDGET
}

zle -N accept-line
2

There isn't any facility that I'm aware of that acts in a manner similar to what you're describing. There is however the ability to create an alias or function within Bash that can facilitate what you want, which sounds similar to what you're describing

Examples

as functions

$ function mygadd() { git add "$@"; }
$ function mcd() { cd "@"; ls -la; }

as aliases

$ alias mycmd='cmd1; cmd2;'

NOTE: With aliases you cannot pass positional parameters. You can pseudo pass arguments by including them in the call to the alias which will then get expanded as a single command line by the shell.

Example

$ alias somecmd='ls -la'
$ somecmd dir1 dir2 

The above will invoke ls -la dir1 dir2 but those 2 arguments were never passed to the alias, rather the alias was expanded to ls -la dir1 dir2 when the command line was evaluated and executed.

Both can be incorporated into your $HOME/.bashrc config files so that they're loaded each time you login.

3
  • I'm pretty sure he meant X to represent a random filename, so you'd need a shell function with parameters. Also, those were 2 separate groups of commands.
    – cjm
    Nov 26, 2013 at 8:52
  • You can't use positional parameters in aliases, at least not in bash. Nov 26, 2013 at 10:06
  • @IgnacioVazquez-Abrams - thanks cleaned that up.
    – slm
    Nov 26, 2013 at 13:17

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .