home *** CD-ROM | disk | FTP | other *** search
- Path: uunet!husc6!necntc!ncoast!allbery
- From: rickers@RUTGERS.EDU@drexel.UUCP (Rick Wargo)
- Newsgroups: comp.sources.misc
- Subject: directory stack manipulation routines for bourne shell
- Keywords: pushd, popd, dirs ...
- Message-ID: <4563@ncoast.UUCP>
- Date: 24 Sep 87 02:39:22 GMT
- Sender: allbery@ncoast.UUCP
- Organization: Drexel University, Phila., Pa.
- Lines: 194
- Approved: allbery@ncoast.UUCP
- X-Archive: comp.sources.misc/8709/15
-
-
-
- Hello ( is there a better greeting that does not sound so boring? ) -
-
- Having been working for a long time under csh and being
- accustomed to the commands pushd and popd, I was saddened to find that
- these commands were not avaiable under my version of Microport Unix
- System V (version 2.2). I had just come across ksh routines to do this
- and thought, hey, what a wonderful way to spend a few hours instead of
- doing something that I should be doing (like real work 8-). The result
- is my first csh program (all other shell programs where written using
- the bourne shell). It is used with a few (four) alias-es and manages a
- directory stack. Hope you find it useful.
-
- If you decide to give this a try, wait until using it before
- reading the next sentence. You shouldn't be reading this unless you've
- tried it already - okay - experienced it? - well ... it may not be
- incredibly fast, but the object was to learn a bit of the c shell.
-
-
- Rickers
- ..!drexel!rickers
-
- ==========c=u=t====h=e=r=e=====================c=u=t====h=e=r=e=========
- #!/bin/csh
- #
- # (-8 tab stops should be at every four for easy readibility 8-)
- #
- # dirstack -- c shell script to manipulate a directory stack
- # written by rickers, august 29, 1987
- #
- # Permission is granted to do what you wish with this code. Happily
- # placed in the public domain. No copyrights - no nutin'.
- #
- # Description of routines:
- # init -- initializes the environment so that the routines can work.
- # dirs -- prints out directory stack.
- # pushd -- push the current directory and change to that specified
- # popd -- pop a directory and change to it
- #
- # These routines pattern themselves after the same functions of the
- # C shell, with a few exceptions. Idea to write this script taken from
- # ksh script originally written by David C. Stewart, and modified to
- # work under MKS tookkit ksh by Keith Ericson, both of Tektronix Inc.
- #
- # To use, some aliases are needed. These follow.
- # set dirstack=/usr/local/lib/dirstack
- # alias initds "set argv=(init \!*); source $dirstack; set argv"
- # alias dirs "set argv=(dirs \!*); source $dirstack; set argv"
- # alias pushd "set argv=(pushd \!*); source $dirstack; set argv"
- # alias popd "set argv=(popd \!*); source $dirstack; set argv"
- # unset dirstack
- #
- # This file should be placed in a known directory. The dirstack variable
- # is just to make the alias look a bit neater.
- #
- # You may be pondering with the question "why did he do it this way?" when
- # i figure it out, i will let you know (maybe). it just seemed the thing to
- # do. note these need routines need to be executed using source. it is
- # faster (it does not invoke another shell) and it makes the variable
- # available to the shell.
- #
- # Oh, btw, the other reason this was written, was to make up for a lacking
- # csh under Microport Unix System V 2.2.
- #
-
- #
- # Depending on argv[1], goto a certain spot in the script and execute
- #
- goto $argv[1]
-
- init:
- # the current directory stack depth
- set ddepth=1
-
- # dstack is the directory stack, set to a max depth of 20
- set dstack=(`pwd` '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '')
- goto finish
-
- #
- # dirs is equivalent (almost) to the csh command `dirs'. It prints out
- # the stack, current directory first, followed by top of stack, and the
- # rest of the stack. it fmt-s the output so it looks nice and does not
- # get fold-ed at 80 chars. It is a bit slow - oh well, so are the rest
- # of the routines.
- #
- dirs:
- set i=$ddepth
- if ( $i == 1 ) set dstack[1]=`pwd`
- cp /dev/null /tmp/$$
- while ($i > 0)
- echo $dstack[$i] >> /tmp/$$
- @ i = $i - 1
- end
- sed "s,$home,\~,g" /tmp/$$ | fmt ; rm /tmp/$$
- goto finish
-
- #
- # pushd is stretching from the csh definition of pushd. given one arg,
- # it pushes the current directory on the stack, and changes to the
- # specified directory. now comes the kludge. to specify a buried
- # directory, use the syntax: pushd + n. note the space between the
- # plus sign and the number. It is there to make life easier and faster.
- # you wouldn't want it any other way now, would you? also, the way it
- # works is different from the way my pushd works (under 4.2BSD). It
- # exchanges the current directory and the specified directory, making
- # the specified directory current. note that the number is offset to
- # the current directory on the dirs print-out ( + 1 is top of stack ).
- # also note that the current directory is not on the top of the stack.
- # pushd given with no arguments is the exact same as pushd + 1, and
- # exchanges the current directory with the top to the stack.
- #
- pushd:
- switch ($#argv)
- case 1:
- if ( $ddepth < 2 ) then
- echo pushd: No other directory.
- goto finish
- else
- @ i = $ddepth - 1
- set temp=$dstack[$i]
- set dstack[$i]=$dstack[$ddepth]
- set dstack[$ddepth]=$temp
- cd $dstack[$ddepth]
- endif
- breaksw
- case 2:
- if ( $ddepth == 1 ) set dstack[1]=`pwd`
- @ ddepth++
- cd $argv[2]
- set dstack[$ddepth]=`pwd`
- breaksw
- case 3:
- @ i = $argv[3]
- @ i = $ddepth - $i
- set temp=$dstack[$i]
- set dstack[$i]=$dstack[$ddepth]
- set dstack[$ddepth]=$temp
- cd $dstack[$ddepth]
- breaksw
- default:
- echo usage: pushd \| pushd name \| pushd +n
- goto finish
- endsw
- goto dirs
-
- #
- # popd is stretching from the csh definition of popd. given no args,
- # it pops one directory from the stack and makes it current, assuming
- # that one exists. again a kludge (same one). to specify a buried
- # directory, use the syntax: popd + n. note the space between the
- # plus sign and the number. same old argument as above. but, ha, this
- # one actually works like the csh popd. oh well, there goes the large
- # deviation. what this action does is removes the specifed directory
- # from the directory stack. again, note that the number is offset to
- # the current directory on the dirs print-out ( + 1 is top of stack ).
- # also note that the current directory is not on the top of the stack,
- # although it is the first printed in the dirs output.
- #
- popd:
- if ( $ddepth == 1 ) then
- echo popd: Directory stack empty.
- goto finish
- else switch ($#argv)
- case 1:
- breaksw
- case 2:
- echo usage: popd \[ + n \]
- goto finish
- breaksw
- case 3:
- if ( ($argv[3] < 1) || ($argv[3] >= $ddepth) ) then
- echo popd: Illegal value.
- goto finish
- endif
- @ i = $ddepth - $argv[3]
- while ( $i < $ddepth )
- @ temp = $i + 1
- set dstack[$i]=$dstack[$temp]
- @ i = $i + 1
- end
- breaksw
- endsw
- endif
- @ ddepth--
- cd $dstack[$ddepth]
- goto dirs
-
- #
- # finishup is the generic get outta here routine.
- #
- finish:
- unset i
- unset temp
-