9

I'm trying to set something up on a server I run, when ever I cd into a public_html folder 95% of the time there's a few commands I will always run to check certain things.

Is there anyway I can hook into cd so if the directory is a public_html, it will automatically run the commands for me?

If I can't hook into the cd command, are there any other things I could do to achieve the outcome I'm after?

I'm running CentOS 5.8.

10

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"
   fi
   builtin cd "$1"
}
  • Ooh, this looks interesting. I've added this to my .bash_profile, and added a echo "Testing..." just above the if, but nothings output. Do I need do something to apply these changes? – TMH Nov 27 '14 at 13:19
  • @TomHart If you didn't start a new session then you have to source the file into your current session by . ~/.bash_profile – UVV Nov 27 '14 at 13:20
  • @TomHart it seems there's no /bin/cd in my CentOS, so this solution might not going to work – UVV Nov 27 '14 at 13:32
  • I've just noticed that now. I found this question which states why unix.stackexchange.com/questions/116955/where-is-cd-located. Still a good solution for system that actually have a /bin/cd though :). – TMH Nov 27 '14 at 13:33
  • 1
    Does not work if you cd -P public_html or cd ~/public_html or has unexpected behaviour if you can't cd into public_html. – Stéphane Chazelas Nov 27 '14 at 16:01
16

With ksh or bash (or zsh):

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

With zsh:

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

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

1

I am not a bash expert but I would take @UVV's answer and modify it just a little so that it does this:

  • instead of checking for public_html, I'd just check for some hook-script file in the target dir $1, say, cd_hook.sh.
  • if that hook-script exists, run it, and move on with the cd

This seems more generic because you'd then be able to apply the cd-hook to any directory if you so choose, by just adding a cd_hook.sh in the said directory.

  • 2
    It seems generic, but you're introducing a security vulnerability. Someone or something only needs to plant a hook-script in /tmp for instance to make you run any code the next time you cd there. You'd want at least to make sure that the hook-script is owned by you, not a symlink, not writable by anyone other than you, that the directory it's in is only writable by you... See Keeping history per working directory (cf. per shell session) for a safer approach. – Stéphane Chazelas Jan 14 '16 at 12:35
  • Thanks for the security insight @StéphaneChazelas. I have to admit I didn't even think about it. – lost-and-found Jan 29 '16 at 12:42
  • I found this question while doing just that: if I cd somewhere, check for a .bashcd file and run it if it exists. – DarkWiiPlayer Dec 23 '18 at 20:36
0

Using powerful zsh approach in bash:

First an easy way to extend bash:

~/.runscripts

#load all scripts inside $1 dir

run_scripts()
{
    for script in $1/*; do

        # skip non-executable snippets
        [ -f "$script" ] && [ -x "$script" ] || continue

        # execute $script in the context of the current shell
        . $script
    done
}

Include in to .bashrc:

. ~/.run_scripts

run_scripts ~/.bashrc.d

You can create ~/.bashrc.d/cdhook with:

#!/bin/bash

chpwd() {
  : #no action
}

cd() {      
   builtin cd $1
   chpwd $1
}

Now is up to you to replace the function:

#list files after cd
chpwd() {
  ls -lah --color
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.