Can I hook into the cd command?

With ksh or bash (or zsh):

cd() {
  builtin cd "[email protected]" || return
  [ "$OLDPWD" = "$PWD" ] || case $PWD in
      (*/public_html) echo do something

With zsh:

  case $PWD in
    (*/public_html) echo do something

(chpwd is a hook function that is called whenever the current working directory changes (by way of cd, pushd, popd...)).

You could add this function to your .bashrc or other startup file (depending on your shell).

cd() {      
   if [ "$1" = "public_html" ]; then
      echo "current dir is my dir"
   builtin cd "$1"

Wrapping cd, an existing command, is not recommended.

A more universal solution would be defining a custom chpwd hook in Bash. (According to tags of this question, I assume you're using Bash)

There's not a complete hook system designed in Bash when compared with other modern shells. PROMPT_COMMAND variable is used as a hook function, which is equivalent to precmd hook in ZSH, fish_prompt in Fish. For the time being, ZSH is the only shell I've known that has a chpwd hook builtin.


If set, the value is interpreted as a command to execute before the printing of each primary prompt ($PS1).

chpwd Hook in Bash

A trick is provided to setup a chpwd equivalent hook in Bash based on PROMPT_COMMAND.

# create a PROPMT_COMMAND equivalent to store chpwd functions
typeset -g CHPWD_COMMAND=""

_chpwd_hook() {
  shopt -s nullglob

  local f

  # run commands in CHPWD_COMMAND variable on dir change
  if [[ "$PREVPWD" != "$PWD" ]]; then
    local IFS=$';'
    for f in $CHPWD_COMMAND; do
    unset IFS
  # refresh last working dir record
  export PREVPWD="$PWD"

# add `;` after _chpwd_hook if PROMPT_COMMAND is not empty

Since we're detecting PWD change directly, the solution works with cd, pushd, and popd.

Note: The main difference between our chpwd implementaion in Bash and the chpwd in ZSH is, PROMPT_COMMAND is not supported in a non-interactive Bash shell.


_public_html_action() {
  if [[ $PWD == */public_html ]]; then
    # actions

# append the command into CHPWD_COMMAND

Source: Create chpwd Equivalent Hook in Bash from my gist.

For anyone want an answer for ZSH. Use chpwd hook in ZSH. Don't define chpwd() function directly. More detail here.