gh@bdblues.altair.fr (gilbert harrus) (01/29/91)
Newsgroups: comp.unix.shell
Subject: ksh emulation of dirs, pushd, and popd of csh
Summary:
Expires:
Sender:
Followup-To:
Distribution: world
Organization: Gip Altair/INRIA, France
Keywords:
Somebody asked for examples of ksh scripts. I just moved from [t]csh
to ksh, and I wrote this "package" to learn more about ksh.
Save in a file, say dirs.ksh, and type : eval . dirs.ksh
Not extensively tested...
gilbert harrus
<--------------- cut here------------------------------>
# Emulation of dirs, pushd and popd of csh under ksh
# Send comments (and bug fixes!) to gh@bdblues.altair.fr
dirs() {
stackdir[0]=`pwd`
typeset -i i=0
while let i!=ndirs ; do
# use print rather than echo here as -n is bsdish
print -n "${stackdir[$i]} "
let i=i+1
done
print
return 0
}
pushd() {
stackdir[0]=`pwd`
typeset -i i j k
if [ $# -gt 1 ]; then
echo "pushd: Too many arguments."
return 1
fi
case "$1" in
# 3 digits less than 200 (otherwise interpreted as a directory name)
+[1-9]|+[1-9][0-9]|+0[1-9]|+0[1-9][0-9]|+1[0-9][0-9])
let i=$1
if [ $i -ge $ndirs ] ; then
echo "pushd: Directory stack not that deep."
return 1
fi
# copy from 0..i-1 to ndirs..ndirs+i-1
let j=0
let k=ndirs
while let j!=i ; do
stackdir[$k]=${stackdir[$j]}
let j=j+1
let k=k+1
if [ $k -ge 511 ] ; then
echo "pushd: fatal internal error."
return 1
fi
done
# move from i to ndirs+i-1 to 0..ndirs-1
let j=i
let k=0
while let k!=ndirs ; do
stackdir[$k]=${stackdir[$j]}
let j=j+1
let k=k+1
done
cd ${stackdir[0]}
;;
*) cd $1
if [ $? -ne 0 ]; then
return 1
fi
let i=ndirs
let ndirs=ndirs+1
let j=i-1
while let i!=0 ; do
stackdir[$i]="${stackdir[$j]}"
let i=i-1
let j=j-1
done
;;
esac
dirs
return $?
}
popd() {
typeset -i i
if [ $# -gt 1 ]; then
echo "popd: Too many arguments."
return 1
fi
# if there is one argument check that it is a +n, with n<ndirs
# set j to position of the entry to be disgarded.
if [ $# -eq 1 ]; then
case "$1" in
+[1-9]|+[1-9][0-9]|+0[1-9]|+0[1-9][0-9]|+1[0-9][0-9])
let j=$1
if [ $j -ge $ndirs ]; then
echo "popd: Directory stack not that deep."
return 1
fi
;;
*)
echo "pushd: Bad directory."
return 1
;;
esac
else
let j=0
fi
let i=ndirs
if [ $i -eq 1 ] ; then
echo "popd: Directory stack empty."
return 1
fi
let ndirs=ndirs-1
let k=j+1
while let j!=i ; do
stackdir[$j]="${stackdir[$k]}"
let j=j+1
let k=k+1
done
cd ${stackdir[0]}
dirs
return $?
}
stackdir=`pwd`
typeset -i ndirs=1
typeset -f dirs
typeset -f pushd
typeset -f popdsanders@peyote.cactus.org (Tony Sanders) (02/08/91)
Here are some csh functions I use converted to ksh (which I'm using now).
# save directory
function sd { pwd > $HOME/.dir/,$1 ; }
# restore directory
function rd { cd `cat $HOME/.dir/,$1` && pwd ; }
Be sure and run "mkdir $HOME/.dir"
Lets you save directories by name and cd back to them with
support for a default directory, which is nice if you run
X-windows and want to sync up all your windows you the same
directory (just run "sd" in one window and "rd" in all the rest).
This one is handy for programmers:
alias vm='if [ -f makefile ]; then vi makefile; else vi Makefile; fi'
in csh I use:
alias vm 'vi [Mm]akefile || vi Makefile'
These are handy for mh users:
function v { vi `mhpath ${*-cur}`; }
alias fll='folders @.'
alias flr='folder -recurse'
alias fls='folders @. -fast'
alias pwf='mhpath'
# cf makes folders look like directories: cf /inbox; cf /news/comp/ai
function cf { folder `echo "$*" | sed -e "s/^\//+/" -e "s/^[^+]/@&/"`; }
Here is my latest working creation:
function warp
{
if [ $# = "0" ]; then
echo "usage: warp warpid [params]"
return 1
fi
# if [ -f "$HOME/.warp/@$warp" ]; then
# . "$HOME/.warp/@$warp" "$1" # unwarp previous warp
# fi
warp="$1"; shift
. "$HOME/.warp/$warp" "$@"
}
It's a front end to the '.' command (source for csh users).
I'm still working out all the details of how I want it to
work and if I should use the unwarp stuff and when.
Here is a sample warp file:
if [ ! -f /SOMEDIRECTORY/rrn ]; then
mount -t newsserverstuff
fi
. $HOME/.path # set default path
PATH=$PATH:/news/rsbin # append news directory bin
export PATH
I have other more complicated examples but I can't really post them.
I have two that setup build environments for different things and
automatically mount and unmount (unwarp) stuff when needed.
For now I unwarp by hand "warp @$warp" when I want.
My original idea was that unwarp would be called automatically when
you warp to something else (if it existed) but the I had the
problem of warping to A in two windows and then warping to B
in one of them. I still wanted to use A in the first window
but it wanted to unmount my directories so I turned it off.
Maybe I need a refcount or something but that's too complex,
I want to keep it simple.
ideas/comments/suggestions welcome:
-- sanders@peyote.cactus.org
First rule of software: Throw the first one away.
and so on...
For every message of the day, a new improved message will arise to overcome it.
IBM UUCP Path: cs.utexas.edu!ibmchs!auschs!sanders.austin.ibm.com!sanders
I am not an IBM representative and I speak only for myself.