Directory Stack in Bash
There is something know as directory stack or DIRSTACK
in bash. Stack is a basic data structure in computer science, where you can store elements on top of each other(like a book stack), but access only most recent one (top).
Here's a small demo - each time i push something on to directory stack, my current working directory is set to that item; every time i pop - we delete the top (left-most ) item from stack, and return to next available item:
$> # pushd navigates to and stores the directory given
$> pwd
/home/xieerqi
$> pushd bin
~/bin ~
$> pushd /etc
/etc ~/bin ~
$> # popd deletes leftmost item, returns to next directory on left$> pwd
/etc
$> popd
~/bin ~
$> pwd
/home/xieerqi/bin
$>
The most recent item is always stored as the top of the stack, even when you use cd
$> dirs
/ /etc ~
$> cd /var
$> dirs
/var /etc ~
$>
The dirs
command allows us to retrieve an nth element from the stack. Using that output as argument to cd
we can navigate to any directory that is on the stack, without affecting the stack itself. Notice bellow how /etc/
and ~
(stack elements 1 and 2) stay the same, even though I change my current working directory (and the top element as well)
$> dirs
/var /etc ~
$> dirs +1
/etc
$> cd $(dirs +1)
$> pwd
/etc
$> dirs
/etc /etc ~
Using DIRSTACK behavior to simulate web browser behavior
You know how in a web browser if you jump from url A to url B and url C, you can kind of go back and forth between them using back and front arrow keys ?
Well, we can do the same in bash with these two functions:
cd()
{
if [ $# -eq 0 ]; then
pushd "$HOME" > /dev/null
else
pushd "$@" > /dev/null
fi
}
cdback()
{
popd > /dev/null
printf "Returned to:%s\n" "$( dirs +0)"
}
Functions have precedence over aliases, thus we can use that to our advantage , and make each cd
call pushd
on every argument it is given (and if none is given, we go back to home directory , same behavior, but it's recorded)
$> pwd
/home/xieerqi
$> cd /etc
$> cd /var
$> cd /usr
$> pwd
/usr
$> cdback
Returned to:/var
$> pwd
/var
$> cd
$> pwd
/home/xieerqi
Directory stack in other shells
csh
has its own directory stack implementation, but ksh
does not. You could use Eddie's implementation
Going up with a for loop
As for going a certain number of dirs up, you could write a function that calls cd ..
certain number of times. For instance, here's my custom function in .bashrc
function goUp # go up x number of dirs
{
num=$1
while [ num -ne 0 ];do
cd ..
num=$( expr $num - 1 )
done
}
# ---
So I would call this as goUp 3
to go up 3 directories, and it would call cd ..
3 times
Using inode number
This method is good when
This trick is often used when the folder name has difficult character/unrecognizable character. We find the inode number of the directory you want to go to using stat
and then use combination of find
and cd
$> stat $HOME/bin/sh/
File: ‘/home/xieerqi/bin/sh/’
Size: 4096 Blocks: 8 IO Block: 4096 directory
Device: 801h/2049d Inode: 5795531 Links: 2
Access: (0775/drwxrwxr-x) Uid: ( 1000/ xieerqi) Gid: ( 1000/ xieerqi)
Access: 2015-08-19 15:27:38.280529273 -0600
Modify: 2016-02-20 17:03:49.822700405 -0700
Change: 2016-02-20 17:03:49.822700405 -0700
Birth: -
$> cd $(find $HOME -inum 5795531 -type d 2>/dev/null)
$> pwd
/home/xieerqi/bin/sh
Of course this might be a bit slow, because find
traverses the whole directory tree recursively.