100 Useful Command-Line Utilities

by Oliver; 2014

3. cd

To move around, we can change directory:
$ cd /some/path
By convention, if we leave off the argument and just type cd we go HOME:
$ cd     # go $HOME
Go to the root directory:
$ cd /	 # go to root
Move one directory back:
$ cd ..  # move one back toward root
To return to the directory we were last in:
$ cd -  # cd into the previous directory
What if you want to visit the directory you were in two or three directories ago? The utilities pushd and popd keep track of the directories you move through in a stack. When you use:
$ pushd some_directory
It acts as a:
$ cd some_directory
except that some_directory is also added to the stack. Let's see an example of how to use this:
$ pushd ~/TMP		# we're in ~/
~/TMP ~
$ pushd ~/DATA		# now we're in ~/TMP
~/DATA ~/TMP ~
$ pushd ~		# now we're in ~/DATA
~ ~/DATA ~/TMP ~
$ popd			# now we're in ~/
~/DATA ~/TMP ~
$ popd			# now we're in ~/DATA
~/TMP ~
$ popd			# now we're in ~/TMP
~
$ 			# now we're in ~/
This is interesting to see once, but I never use pushd and popd. Instead, I like to use a function, cd_func, which I stole off the internet. It allows you to scroll through all of your past directories with the syntax:
$ cd --
Here's the function, which you should paste into your setup dotfiles (e.g., .bash_profile):
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
        index=${the_new_dir:1};
        [[ -z $index ]] && index=1;
        adir=$(dirs +$index);
        [[ -z $adir ]] && return 1;
        the_new_dir=$adir;
    fi;
    [[ ${the_new_dir:0:1} == '~' ]] && the_new_dir="${HOME}${the_new_dir:1}";
    pushd "${the_new_dir}" > /dev/null;
    [[ $? -ne 0 ]] && return 1;
    the_new_dir=$(pwd);
    popd -n +11 2> /dev/null > /dev/null;
    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 > /dev/null;
            cnt=cnt-1;
        fi;
    done;
    return 0
}
Also in your setup dotfiles, alias cd to this function:
alias cd=cd_func
and then you can type:
$ cd --
 0  ~
 1  ~/DATA
 2  ~/TMP
to see all the directories you've visited. To go into ~/TMP, for example, enter:
$ cd -2
Changing the subject and dipping one toe into the world of shell scripting, you can put cd into constructions like this:
if ! cd $outputdir; then echo "error. couldn't cd into "${outputdir}; exit; fi
or, more succinctly:
cd $outputdir || exit
This can be a useful line to include in a script. If the user gives an output directory as an argument and the directory doesn't exist, we exit. If it does exist, we cd into it and it's business as usual.

<PREV   NEXT>