Neither one nor Many
Software engineering blog about my projects, geometry, visualization and music.
I prefer ksh (Version JM 93u+ 2012-02-29) for my shell (with "set -o vi"). Not that it's soooo much better than bash as a cli (and it's probably pwnd by some of zsh's features like programmable autocomplete). But I do find it alot cleaner than bash for scripting. Anyway, currently I've given all machines I work with a /bin/ksh and chsh'd it for my user, but I noticed I missed bookmarking the current directory with "pushd ." for returning to it later with "popd" (after i.e. some subtask that will make you endup /nowhere/near/your/old/far/away/path).
Sometimes you just don't want to open a new tab in screen. (And you are right, you could of course also use goto.cpp for bookmarking ) An alternative solution would be starting- and exiting a subshell.
So I googled and found this stack overflow answer which has a pretty nice pushd/popd/dirs implementation. But it behaves a little different: "pushd /usr" bookmarks and changes to that directory (the normal behaviour). But what I often want is to store a directory right before I'm about to leave it. (Chances are I didn't use "pushd" but "cd" to get there in the first place.) Normally you simply use "pushd ." to put it on the stack (and ignore the useless changedir on the side ). But this implementation is explicitly designed so that the current directory is already (and always) the first (or zeroth position) on the stack and from that line of thought it would be "useless" to put it as a "duplicate" in the list.
I still want to use pushd on $PWD, so I commented these four lines in dirstack.ksh:
# check for duplicate stack entries
# current "top of stack" = ids; compare ids+dsdel to $PWD
# either "ids" or "dsdel" must increment with each loop
#
(( ids = 1 )) # loop from bottom of stack up
(( dsdel = 0 )) # no deleted entries yet
while [ ids+dsdel -le sd ] ; do
>>>> #if [ "${dir_stack[ids+dsdel]}" = "$PWD" ] ; then
>>>> # (( dsdel = dsdel + 1 )) # logically remove duplicate
>>>> #else
if [ dsdel -gt 0 ] ; then # copy down
dir_stack[ids]="${dir_stack[ids+dsdel]}"
fi
(( ids = ids + 1 ))
>>>> #fi
done
Then I remembered my book (that has caused me many jealous colleagues :+) also provided pushd and popd as examples in the appendix .
So I was curious to see if these were usable (the book is from 1995).
* by my guess
SuSE provides these scripts in /usr/share/ksh/fun so I didn't need to type them in. If you need them, I tarballed them into kshfun.tar.gz (md5=7173831211d3d54f26f630f3cc720282). I was surprised by /usr/share/ksh/fun/dirs, they re-alias "cd" with a custom "_cd" function that does basically "pushd" all the time, with a stack of max. 32 dirs. That's a cool idea, you can view your stack with "dirs" or even use the "mcd" (menu change dir) command. You use this "cd" alias like "cd N" as well, where N is the index on the stack (given by "dirs" output). And pushd and popd work on this same stack.
For your .kshrc profile:
. /usr/share/ksh/fun/popd <<<< includes pushd as well **
. /usr/share/ksh/fun/dirs <<<< if you also want the custom cd + dirs
**ls -althr /usr/share/ksh/fun:
total 16K
-rwxr-xr-x 1 root root 2.5K Jun 6 2012 pushd
-rwxr-xr-x 1 root root 2.3K Jun 6 2012 dirs
lrwxrwxrwx 1 root root 5 Jan 19 23:43 popd -> pushd <<<< symlink
trigen@ip-10-235-45-12:/etc/apache2> cd /var/log/
/var/log
trigen@ip-10-235-45-12:/var/log> dirs
1) /var/log
2) /etc/apache2
3) /usr/local/src
4) ~
trigen@ip-10-235-45-12:/var/log> cd 2 <<<< If you have a directory named '2', use "cd ./2" :P
/etc/apache2
trigen@ip-10-235-45-12:/etc/apache2> mcd
1) /etc/apache2
2) /var/log
3) /usr/local/src
4) ~
Select by number or enter a name: 3
/usr/local/src
trigen@ip-10-235-45-12:/usr/local/src>
or what I was talking about:
trigen@ip-10-235-45-12:/home/trigen> cd /usr/local/lib
/usr/local/lib
trigen@ip-10-235-45-12:/usr/local/lib> pushd .
/usr/local/lib ~ /usr/local/lib
trigen@ip-10-235-45-12:/usr/local/lib> cd /
/
trigen@ip-10-235-45-12:/> popd <<<< In this trivial example "cd -" (where - is previous dir) would also work.
/usr/local/lib ~ /usr/local/lib
trigen@ip-10-235-45-12:/usr/local/lib>