Linux/Cygwin Tip: Change directory like a command line commando :)

If you are a software developer or system administrator who spend lot of time in CLIs like bash shell & cygwin, you might love this tip. cd command (change directory) is undoubtedly one of the frequently used command. There is a version of cd command (cd -) which helps jumping between directories, kind of like pressing jump button for changing channels in TV remote control. I use it a lot, both in remote control & for changing directories :) .

cd -

cd - is an awesome command for jumping between directories. But the limitation with that is, it can remember only the last directory you were in before. What if we have a clipboard/history type functionality for cd command. Yep, that would make our life lot easier.

Disclaimer: This is not something I came up with originally. I just discovered it in the default .bashrc file created by cygwin installation. Thanks to Petar Marinov for writing this function and making command line more fun.

OK, how you do this? Just copy the following function (“copy to clipboard” icon on top-right of code block) and paste it in the last line of your .bashrc file. It will be under your home directory in Unix/Linux machine. For cygwin users, you might find it in c:\cygwin\home\user_id\.bashrc file.

 cd_func ()
 {
   local x2 the_new_dir adir index
   local -i cnt

   if [[ $1 ==  "--" ]]; then
     dirs -v
     return 0
   fi

   the_new_dir=$1
   [[ -z $1 ]] && the_new_dir=$HOME

   if [[ ${the_new_dir:0:1} == '-' ]]; then
     #
     # Extract dir N from dirs
     index=${the_new_dir:1}
     [[ -z $index ]] && index=1
     adir=$(dirs +$index)
     [[ -z $adir ]] && return 1
     the_new_dir=$adir
   fi

   #
   # '~' has to be substituted by ${HOME}
   [[ ${the_new_dir:0:1} == '~' ]] && the_new_dir="${HOME}${the_new_dir:1}"

   #
   # Now change to the new dir and add to the top of the stack
   pushd "${the_new_dir}" > /dev/null
   [[ $? -ne 0 ]] && return 1
   the_new_dir=$(pwd)

   #
   # Trim down everything beyond 11th entry
   popd -n +11 2>/dev/null 1>/dev/null

   #
   # Remove any other occurence of this dir, skipping the top of the stack
   for ((cnt=1; cnt <= 10; cnt++)); do
     x2=$(dirs +${cnt} 2>/dev/null)
     [[ $? -ne 0 ]] && return 0
     [[ ${x2:0:1} == '~' ]] && x2="${HOME}${x2:1}"
     if [[ "${x2}" == "${the_new_dir}" ]]; then
       popd -n +$cnt 2>/dev/null 1>/dev/null
       cnt=cnt-1
     fi
   done

   return 0
 }

alias cd=cd_func

After you save .bashrc file, type the following command from home directory.

source .bashrc

Thats about it. Type cd command multiple times moving around different folders and type the following command.

 $ cd --
 0  /cygdrive/c/cygwin
 1  /cygdrive/c/scratch
 2  /cygdrive/c/Program Files
 3  /cygdrive/c/Documents and Settings
 4  ~

So, if I want to go to scratch folder, I just have to type cd -1 and for home directory, cd -4. The function we added can hold up to 10 items in the history.

Yes, I understand, you can also use history command to do similar job. But the difference here is, it is very specific for changing directories.

Thoughts, comments, questions ?

Note: I have tested this function only in Ubuntu & Cygwin. I am not sure if it will work on korn or other shells. If someone could make it work in other shell environments and like to share, please feel free to post it in the comments.

  1. Derek Montgomery

    Very useful script. Thanks!!

  2. This is what I was trying to implement, its a kewl function, now borrowing from you… I tried in Mac-bash and so far it works fine…will let you know if I find any issue. Thanks again

  3. Hi.. Can anyone tell me how to install ngspice using cygwin….

Leave a Comment


NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

 
Your Ad Here