[alt.sources] Pushd, popd, dirs for stock SysV.3 Bourne shell

pcg@cs.aber.ac.uk (Piercarlo Grandi) (09/26/90)

You wwill find appended a small shell script that defines under a stock
System V Bourne shell the pushd, popd, dirs commands of csh(1). They are
trivially adapted to the Korn shell. I have taken care to make them as
robust as possible.

-----------------------------cut here-------------------------------
DIRS=''

# We do a few contortions to ensure correct behaviour
# if directory pathnames contain spaces et similia.
# The things that substitute ~ for $HOME are commented
# out; you may want to comment them in.

cwd()
{
    pwd				# | sed 's|'"$HOME"'/|~/|'
}

chdir()
{
    cd "$1"			# cd `echo "$1" | sed 's|^~/|'"$HOME"'/|`
}

pushd()
{
    CWD="`pwd`"

    case "$1" in

    '')	case "$DIRS" in
	'') echo "directory stack empty"; return 1;;
	esac
	set $DIRS; eval cd "$1"; >/dev/null || return 1
	shift; DIRS="'$CWD' $@"; cwd;;

    *)	chdir "$1" || return 1
	DIRS="'$CWD' $DIRS";;

    esac
    return 0
}

popd()
{
    case "$DIRS" in
    '') echo "directory stack empty"; return 1;;
    esac
    set $DIRS; eval cd "$1"
    shift; DIRS="$*"; cwd
    return 0
}

dirs()
{
    CWD="`pwd`" || return 1
    eval echo "'$CWD' $DIRS"	# | sed 's|'"$HOME"'/|~/|g'
    return 0
}

---------------------------cut here as well----------------------------
--
Piercarlo "Peter" Grandi           | ARPA: pcg%uk.ac.aber.cs@nsfnet-relay.ac.uk
Dept of CS, UCW Aberystwyth        | UUCP: ...!mcsun!ukc!aber-cs!pcg
Penglais, Aberystwyth SY23 3BZ, UK | INET: pcg@cs.aber.ac.uk

barto@megatek.UUCP (David Barto) (09/27/90)

In article <PCG.90Sep26164749@odin.cs.aber.ac.uk> pcg@cs.aber.ac.uk (Piercarlo Grandi) writes:
>
>You will find appended a small shell script that defines under a stock
>System V Bourne shell the pushd, popd, dirs commands of csh(1). They are
>trivially adapted to the Korn shell. I have taken care to make them as
>robust as possible.
>

pushd, popd, and dirs --- written by Chris Bertin
Pixel Computer Inc. ...!wjh12!pixel!pixutl!chris
as modified by Patrick Elam of GTRI
modified by david barto to allow 'pushd +n'

cd is a function, which uses the 'builtin' keyword, available for
those who have the BRL mods to the shell.  (I think this can be changed
to 'eval'.)  It will look for PCDPATH and do chdirs down that path if
the directory can be found on it.

PCDPATH=". $HOME /burt/prj/common /burt/prj/sparc /archive2"
export PCDPATH
-----

cd () {
	PREVDIR="$CWD" 
	result=1
	if [ $# -lt 1 ] ; then
		builtin cd
		result=0
	elif [ -d $1 ] ; then
		builtin cd "$1" 
		result=0
	else
	    for i in $PCDPATH
	    do
		nxtdir=$i/$1
		# echo "try $nxtdir"
		if [ $result != 0 -a -d $nxtdir ] ; then
		    builtin cd "$nxtdir"
		    result=0
		fi
	    done
	    unset nxtdir
	fi
	if [ $result != 0 ] ; then
	    echo "$1: directory not found"
	else
	    CWD=`pwd` export CWD 
	    set +u 
	    if [ "$CWD" = "$HOME" ] 
	    then
		PFX="$HOST" 
		PS1=:~
	    else
		PS1=`echo "$CWD" | sed -e "s!^$HOME!~!"` PFX="$HOST": 
	    fi
	    umask 022
	    echo "$CWD" | egrep -s "/burt/prj/common|/x"
	    [ $? = 0 ] && umask 002
	    if [ "$TERM" = "wy75" ]
	    then
		wy75-title $PS1
		PS1="$PFX %e_ "
	    elif [ "$TWM_RUNNING" = 1 ]
	    then
		if [ "$TTY" != "" ]
		then
		    twm-title "$TTY:$PFX$PS1"
		else
		    twm-title "XX:$PFX$PS1"
		fi
		PS1="%e_ "
	    else
		PS1="$PFX$PS1 %t%n%e_ " 
	    fi
	    unset PFX 
	    set -u 
	fi
	return $result
}

# pushd, popd, and dirs --- written by Chris Bertin
# Pixel Computer Inc. ...!wjh12!pixel!pixutl!chris
# as modified by Patrick Elam of GTRI
# modified by david barto to allow 'pushd +n'

pushd () {
	SAVE=`pwd`
	_DSTACK="$SAVE $_DSTACK"
	if [ "$1" = "" ] 
	then
		if [ "$_DSTACK" = "$SAVE " ]
		then
			echo "pushd: directory stack empty."
			_DSTACK=""
			return 1
		fi
		set $_DSTACK
		cd $2
		set $_DSTACK
		shift 2
		_DSTACK="$SAVE $*"
	else
		case "$1" in
		+*)
			count=`echo $1 | sed 's/+//'`
			set $_DSTACK
			if [ $count -ge $# ] ; then
				echo "pushd: directory stack not that deep"
				shift
				_DSTACK=$*
				return 1
			fi
			TMP=
			while [ $count -gt 0 ]
			do
				TMP="$TMP $1"
				shift
				count=`expr $count - 1`
			done
			TD=$1
			shift
			_DSTACK="$TMP $*"
			unset TMP
			if [ -d $TD ]
			then
				cd $TD >&-
				unset TD
			else
				popd > /dev/null
				return 1
			fi
			;;
		*)
			cd $1
			if [ $? -eq 1 ] ; then
				popd > /dev/null
				return 1
			fi
			;;
		esac
	fi
	dirs
	return 0
}

popd () {
	if [ "$_DSTACK" = "" ]; then
		echo "popd: Directory stack empty"
		return 1
	fi
	case "$1" in
	+*)
		count=`echo $1 | sed 's/+//'`
		case "$count" in
		0)
			echo "popd: Must have positive count"
			return 1
			;;
		1)
			popd
			return 0
			;;
		*)
			_TMPSTK="`pwd` $_DSTACK"
			set $_TMPSTK
			if [ $count -gt $# ]; then
				echo "pushd: directory stack not that deep"
				return 1
			fi
			TMP=
			while [ $count -ge 1 ]
			do
				TMP="$TMP $1"
				shift
				count=`expr $count - 1`
			done
			shift		# trash dir requested
			_DSTACK="$* $TMP"
			set $_DSTACK
			shift		# trash 'pwd' from the top of the stack
			_DSTACK="$*"
			;;
		esac
		;;
	*)
		set $_DSTACK
		cd $1
		set $_DSTACK
		shift
		_DSTACK=$*
		;;
	esac
	dirs
	return 0
}

dirs () {
	echo "`pwd` $_DSTACK"
	return 0
}

xchng () {	# exchanged top two entries on the stack
	if [ "$_DSTACK" = "" ]
	then
		echo exchange directory stack empty
		return 1
	else
		pushd
		return 0
	fi
}
-- 
David Barto	uunet!megatek!barto	barto@network.ucsd.edu

jwc@Unify.Com (J. William Claypool) (09/28/90)

In article <PCG.90Sep26164749@odin.cs.aber.ac.uk> pcg@cs.aber.ac.uk (Piercarlo Grandi) writes:
>
>You wwill find appended a small shell script that defines under a stock
>System V Bourne shell the pushd, popd, dirs commands of csh(1). They are
>trivially adapted to the Korn shell. I have taken care to make them as
>robust as possible.

Well... since you mentioned it... Here is an implementation of directory
stack for SysV Bourne shell which I've had floating around for a while.
I took a similar approach.  I didn't make any attempt to handle space in a
directory name.  I believe that it duplicates the full functionality of csh.

It also initializes the directory stack from $HOME/.dirstk if that file is
present.

-------------------- cut here --------------------
dirs(){
case $# in
    0)  echo `pwd` $dirstk |
	sed -e "s;$HOME;~;g" -e 'y/\ /\\n/' |
	nl -v0 ;;
    1)  case $1 in
	    -l) echo `pwd` $dirstk ;;
	    *)  echo "usage: dirs [ -l ]" ;;
	esac ;;
    *)  echo "usage: dirs [ -l ]" ;;
esac
}

popd(){
case $# in
    0)  set $dirstk
	case $# in
	    0)  echo "popd: Directory stack is empty." ;;
	    *)  if eval cd $1 ; then
		    shift
		    dirstk="$*"
		    dirs
		fi
	esac ;;
    1)  case $1 in
	    +[0-9]|+[0-9][0-9])
		cnt=`echo $1 | sed -e 's;+;;'`
		set $dirstk
		case $cnt in
		    0|00)
			if eval cd $1 ; then
			    shift
			    dirstk="$*"
			    dirs
			fi ;;
		    *)  if [ $# -ge $cnt ] ; then
			    svdirs=
			    while [ $cnt -gt 1 ] ; do
				svdirs="$svdirs $1"
				shift
				cnt=`expr $cnt - 1`
			    done
			    shift
			    dirstk="$svdirs $*"
			    dirs
			else
			    echo "popd: Directory stack not that deep."
			fi ;;
		esac ;;
	    *)  echo "usage: popd [ +n ]" ;;
	esac ;;
    *)  echo "usage: popd [ +n ]" ;;
esac
}

pushd(){
case $# in
    0)  set $dirstk
	case $# in
	    0)  ;;
	    *)  d1=`pwd`
		if eval cd $1 ; then
		    shift
		    dirstk="$d1 $*"
		    dirs
		fi ;;
	esac ;;
    1)  case $1 in
	    +[0-9]|+[0-9][0-9])
		cnt=`echo $1 | sed -e 's;+;;'`
		set $dirstk
		if [ $# -ge $cnt ] ; then
		    svdirs=`pwd`
		    while [ $cnt -gt 1 ] ; do
			svdirs="$svdirs $1"
			shift
			cnt=`expr $cnt - 1`
		    done
		    if eval cd $1 ; then
			shift
			dirstk="$* $svdirs"
			dirs
		    fi
		else
		    echo "pushd: Directory stack not that deep."
		fi
		;;
	    +*) echo "usage: pushd [ +n | <dir> ]" ;;
	    *)  dirstk="`pwd` $dirstk"
		if eval cd `echo $1 | sed -e "s;~;$HOME;"` ; then
		    dirs
		else
		    set $dirstk
		    shift
		    $dirstk="$*"
		fi ;;
	esac ;;
    *) echo "usage: pushd [ +n | <dir> ]" ;;
esac
}

svds(){
dirs -l > $HOME/.dirstk
}

if [ -s $HOME/.dirstk ] ; then
    dirstk=`cat $HOME/.dirstk`
    popd
else
    dirstk=
fi
-------------------- cut here --------------------
-- 

Bill Claypool +1 916 920 1830 x341| I know what I know if you know what I mean
jwc@Unify.Com                     |--------------------------------------------
   ...!{csusac,pyramid}!unify!jwc |   SCCA SFR Solo II   74 es  1984 CRX 1.5