22

I'd like to execute a particular bash function when I enter a new directory. Somethink like:

alias cd="cd $@ && myfunction"

$@ doesn't work there, and adding a backslash doesn't help. I'm also a little worried about messing with cd, and it would be nice if this worked for other commands which changed directory, like pushd and popd.

Any better aliases/commands?

Paul Biggar
  • 27,579
  • 21
  • 99
  • 152

4 Answers4

24

Aliases don't accept parameters. You should use a function. There's no need to execute it automatically every time a prompt is issued.

function cd () { builtin cd "$@" && myfunction; }

The builtin keyword allows you to redefine a Bash builtin without creating a recursion. Quoting the parameter makes it work in case there are spaces in directory names.

The Bash docs say:

For almost every purpose, shell functions are preferred over aliases.

Dennis Williamson
  • 346,391
  • 90
  • 374
  • 439
  • it doesn't cover his concern about pushd, popd etc; and making a function for every case makes it perhaps more complex than a prompt command. – falstro Jul 29 '10 at 16:15
20

The easiest solution I can come up with is this

myfunction() {
  if [ "$PWD" != "$MYOLDPWD" ]; then
    MYOLDPWD="$PWD";
    # strut yer stuff here..
  fi
}

export PROMPT_COMMAND=myfunction

That ought to do it. It'll work with all commands, and will get triggered before the prompt is displayed.

falstro
  • 34,597
  • 9
  • 72
  • 86
  • 1
    Just add `printf "\e]1;$PWD\a"` and bam(!), tab name is changed to pwd. – Fadi Jul 16 '14 at 15:04
  • @Fadi while true, most people simply add an escape sequence to the prompt itself for that, it doesn't really matter that it gets updated with every prompt (rather than just when changing directories), as it won't be noticable. – falstro Jul 16 '14 at 15:07
8

There are a few other versions of this out there, including

  • smartcd, which I wrote, and has a ton of features including templating and temporary variable saving
  • ondir, which is smaller and much simpler

Both of these support both bash and zsh

cxreg
  • 11,088
  • 1
  • 20
  • 10
2

I've written a ZSH script utilizing the callback function chpwd to source project specific ZSH configurations. I'm not sure if it works with Bash, but I think it'll be worth a try. If it doesn't find a script file in the directory you're cd'ing into, it'll check the parent directories until it finds a script to source (or until it reaches /). It also calls a function unmagic when cd'ing out of the directory, which allows you to clean up your environment when leaving a project.

http://github.com/jkramer/home/blob/master/.zsh/func/magic

Example for a "magic" script:

export BASE=$PWD # needed for another script of mine that allows you to cd into the projects base directory by pressing ^b

ctags -R --languages=Perl $PWD # update ctags file when entering the project directory

export PERL5LIB="$BASE/lib"

# function that starts the catalyst server
function srv {
  perl $BASE/script/${PROJECT_NAME}_server.pl
}

# clean up
function unmagic {
  unfunction src
  unset PERL5LIB
}
Alexis Wilke
  • 19,179
  • 10
  • 84
  • 156
jkramer
  • 15,440
  • 5
  • 47
  • 48