[can.usrgroup] Group changing in a shell script...

mason@tmsoft.uucp (Dave Mason) (09/01/89)

In article  telly!moore!telly!tmsoft!psican!nik writes:
>
>I'm having problems running "newgrp" within a shell script because
>it seems that newgrp destroys the environment. Once the newgrp command
>is encountered the shell script just stops. Why?

newgrp is a command specially recognized by the shell (like 'cd' or
'umask') and it treats it as if there were an 'exec' before it.  Thus
the current shell is replaced by newgrp which then execs a shell,
possibly after changing group (if you were allowed to).  Thus any
non-exported variables will be lost, and the current shell script,
etc.  I ran into this problem several years ago.  Here is my
solution... note that it is a horrible hack, but it exhibits some
interesting tidbits of shell programming:
---------------newgrp.sh--------------
# newgrp.sh - Copyright (C) 1986 Dave Mason, TM Software Associates mason@tmsoft
# Can be used for any purpose, including being sold, as long as this copyright
# notice remains, and that the copyright holder is not held responsible for
# any use or abuse of this software.

# To use, put in some bin directory, and link to the names of groups that
# you can newgrp(1) to (eg for me: uulogins).  Then you can create a sub-shell
# running as the specified group by just typing e.g.:	uulogins
# Or run a command as the group by typing:    uulogins emacs /usr/lib/uucp/L.sys
# If there is an entry in CDPATH that has a directory matching the groupname,
# in your environment, then a first argument of - will cause it to cd to the
# group home directory, and the bin directory within that group home directory
# will be added to PATH.
umask 2

GROUP="`basename $0`";export GROUP
# the following 4 lines are for GROUP directories & GROUP bin directories
# may be safely omitted if you don't have group directories
case "$1" in
	'-')	CD="cd $GROUP"
		CC='if test -d bin; then PATH=$PATH:`pwd`/bin;fi'
		shift;;
	*)	CD=''
		CC='PATH=$PATH`(cd $GROUP && if test -d bin; then echo :\`pwd\`/bin;fi) 2>/dev/null`'
esac

newgrp $GROUP 9<&0 <<EOF
eval \`id|sed -e 's/[0-9]*(//g' -e 's/)//g'\`
if [ "\$gid" != "$GROUP" ] ; then exit 1 ; fi
PSBASE="\$uid+$GROUP";export PSBASE
PS1="\$PSBASE$WORK>";export PS1

# the following 5 lines are for GROUP directories & GROUP bin directories
# may be safely omitted if you don't have group directories
$CD
case "$GROUPPATH" in '') ;;
	*)	$CC;export PATH
esac

rm -f /tmp/sh$$?
case $# in
	0)	exec ${SHELL-/bin/sh} 0<&9 ;;
# the following line loads my shell functions, remove if you like
	*)	if [ "$SHELLFN" != "" ] ; then . $SHELLFN; fi
		$* 0<&9
esac
EOF
-------------------------end of included file-------------------
Note that file descriptor 9 MAY be used for something, if so save
stdin on some other fd.

	Enjoy	../Dave