pushd/popd as ksh functions: possible in unix pc ksh?
Bruce Lilly
bruce at balilly.UUCP
Sun Dec 30 00:20:30 AEST 1990
In article <1990Dec28.054110.13613 at shibaya.lonestar.org> afc at shibaya.lonestar.org (Augustine Cano) writes:
>
>I just typed in the pushd/popd functions found in "The Korn Shell" by Bolsky
>and Korn and guess what... they don't work! Is this because of our ancient
>version? Has anybody attempted this? Does anybody have a working version
>of pushd/popd as ksh functions that work on our antiquated shell?
In addition to Thad's comments, I can offer the following which ``sort
of'' work (seems to be a minor problem after su'ing). These are the
``dirs'', ``cd'', and ``mcd'' functions described in the same section as
``pushd'' and ``popd''. The push and pop stuff is in-line. I hope this
helps. I've also included a function ``su'' which allows one to run a
shell as another user in a new window (using windy) -- with this, I only
run a single login window, as I can then run a new window (e.g. as root)
to do other things.
unalias cd
alias cd=_cd
function _cd
{
typeset dir=$1
integer n=0 type=4
case $1 in
-|-1|2) # cd -
n=_push_top type=1
;;
-[1-9]|-[1-9][0-9]) # cd -n
n=_push_top+${1#-}-1 type=2
;;
1) # keep present directory
print -r - "$PWD"
return
;;
[2-9]|[1-9][0-9]) # cd n
n=_push_top+${1}-2 type=2
;;
*) if ((_push_top <= 0))
then type=3 n=_push_max
fi
;;
esac
if ((type<3))
then if ((n >= _push_max))
then print cd: Directory stack not that deep.
return 1
else dir=${_push_stack[n]}
fi
fi
case $dir in
\~) dir=$HOME
;;
\~/*) dir=$HOME${dir#~}
;;
\~*) dirleft=${dir%%/*}
dirright=${dir##*/}
if [ "$dirleft" = "$dirright" ]
then
dirright=
else
dirright=/$dirright
fi
username=${dirleft#~}
userhome=`grep ^$username: /etc/passwd | cut -d: -f6 | sed -e "s,/$,,"`
dir=$userhome$dirright
unset dirright dirleft username userhome
;;
esac
\cd "${dir:-$@}" > /dev/null || return 1
dir=${OLDPWD#$HOME/}
case $dir in
$HOME)
dir=\~
;;
/*) ;;
*) dir=\~/$dir;;
esac
case $type in
1) # swap first two elements
_push_stack[_push_top=_push_top-1]=$dir
;;
2|3) # put $dir on top and shift down by one until top
integer i=_push_top
for dir in "$dir" "${_push_stack[@]}"
do ((i > n)) && break
_push_stack[i]=$dir
i=i+1
done
;;
4) # push name
_push_stack[_push_top=_push_top-1]=$dir
;;
esac
print -r - "$PWD"
}
function dirs
{
typeset dir=${PWD#$HOME/}
case $dir in
$HOME)
dir=\~ ;;
/*) ;;
*) dir=\~/$dir;;
esac
print -r - "$dir ${_push_stack[@]}"
}
function mcd
{
typeset dir="${PWD#$HOME/}"
case $dir in
~/*) dir=$HOME${dir#~};;
esac
case $dir in
$HOME)
dir=\~
;;
/*) ;;
*) dir=\~/$dir;;
esac
OLDPS3=$PS3
PS3='Select by number or enter a name: '
select dir in "$dir" "${_push_stack[@]}"
do if _cd $REPLY
then return
fi
done
PS3=$OLDPS3
}
function su {
if [ "$1" = "-" ]
then
# no problem - .profile will take care of things
windy -b /bin/su $*
else
# need to make sure ksh is used
# but can't simply force "-" because that will clear environment
# need to take care of ENV and HISTFILE
tempENV=$ENV
tempHISTFILE=$HISTFILE
tempHISTSIZE=$HISTSIZE
tempHOME=$HOME
tempMAIL=$MAIL
tempMAILPATH=$MAILPATH
if [ $# = 0 ]
then
# no args - root is default
suuser=root
suhome=""
else
# have some args - $1 must be user
suuser=$1
suhome=`grep "^${suuser}:" /etc/passwd | cut -d: -f6 | sed -e "s,/$,,"`
shift
fi
ENV=${suhome}/.kshrc
HISTFILE=${suhome}/.kshistory
HISTSIZE=999
HOME=${suhome:=/}
unset MAIL
MAILPATH=$MAILPATH:/usr/mail/$suuser:/usr/spool/uucppublic/$suuser
windy -b /bin/su ${suuser} -c "exec /bin/ksh $*"
ENV=$tempENV
HISTFILE=$tempHISTFILE
HISTSIZE=$tempHISTSIZE
HOME=$tempHOME
MAIL=$tempMAIL
MAILPATH=$tempMAILPATH
unset suuser suhome tempENV tempHISTFILE tempHISTSIZE tempHOME tempMAIL tempMAILPATH
fi
}
--
Bruce Lilly blilly!balilly!bruce at sonyd1.Broadcast.Sony.COM
More information about the Comp.sys.att
mailing list