[comp.unix.shell] how to force rsh to exit with status of remote command

rodgers@maxwell.mmwb.ucsf.edu (R. P. C. Rodgers, M.D.) (06/03/91)

Dear Fellow Netlanders,

Reading the manual pages concerned with rsh and experimentation thus
far fail to show how rsh can be made to exit with the status of the command
it is executing on a remote host (if indeed this is possible...).
The rsh always seems to exit with a status of 0, even if the command on the
remote hosts fails.

Thanks in advance for any pointers/solutions.

Cheerio, Rick Rodgers
R. P. C. Rodgers, M.D.         (415)476-2957 (work) 664-0560 (home)
UCSF Laurel Heights Campus     UUCP: ...ucbvax.berkeley.edu!cca.ucsf.edu!rodgers
3333 California St., Suite 102 Internet: rodgers@maxwell.mmwb.ucsf.edu
San Francisco CA 94118 USA     BITNET: rodgers@ucsfcca

Tom Christiansen <tchrist@convex.COM> (06/03/91)

From the keyboard of rodgers@maxwell.mmwb.ucsf.edu (R. P. C. Rodgers, M.D.):
:Reading the manual pages concerned with rsh and experimentation thus
:far fail to show how rsh can be made to exit with the status of the command
:it is executing on a remote host (if indeed this is possible...).
:The rsh always seems to exit with a status of 0, even if the command on the
:remote hosts fails.

rsh will exit !0 if it fails to make the connection, or loses it,
or whatnot.  I use maarten Litmaath's "ersh" front end [enclosed]
when I want an rsh that gives me the remote status.

--tom

#!/bin/sh
# @(#)ersh 2.4 91/01/30 Maarten Litmaath
# This rsh front-end returns the exit status of the remote command.
# It works OK with sh/csh-compatible shells on the remote (!) side.
# If there is no remote command present, /usr/ucb/rlogin is invoked.
# Usage: see rsh(1).

unset hostname lflag nflag user

case $1 in
-l)
	;;
*)
	hostname=$1
	shift
esac

case $1 in
-l)
	lflag=-l
	user=$2
	shift 2
esac

case $1 in
-n)
	nflag=-n
	shift
esac

case $hostname in
'')
	hostname=$1
	shift
esac

case $# in
0)
	exec /usr/ucb/rlogin $lflag ${user+"$user"} "$hostname"
esac

AWK='
	NR > 1 {
		print prev;
		prev = $0;
		prev1 = $1;
		prev2 = $2;
	}
	NR == 1 {
		prev = $0;
		prev1 = $1;
		prev2 = $2;
	}
	END {
		if (prev1 ~ /[0-9]*[0-9]0/)
			exit(prev1 / 10);
		if (prev1 == "0")
			exit(prev2);
		print prev;
		exit(1);
	}
'

exec 3>&1

/usr/ucb/rsh "$hostname" $lflag ${user+"$user"} $nflag \
	"(${*-:}); sh -c '"'echo "$0 $1" >&2'\'' $?0 "$status"' \
	2>&1 >&3 3>&- | awk "$AWK" >&2 3>&-
--
Tom Christiansen		tchrist@convex.com	convex!tchrist
	    "Perl is to sed as C is to assembly language."  -me

mjm@eleazar.dartmouth.edu (Andy Behrens) (06/04/91)

rodgers@maxwell.mmwb.ucsf.edu (R. P. C. Rodgers, M.D.) writes:
>The rsh always seems to exit with a status of 0, even if the command
> on the remote hosts fails.

This question gets asked fairly often.  Here's a replacement for rsh
that you should install on the local machine. The remote machine
doesn't need to be changed provided you are running a fairly "normal"
shell.

Thanks to Maarten Litmaath for this little gem.

------------------------------ CUT HERE ------------------------------
#!/bin/sh
# @(#)ersh 2.4 91/01/30 Maarten Litmaath
# This rsh front-end returns the exit status of the remote command.
# It works OK with sh/csh-compatible shells on the remote (!) side.
# If there is no remote command present, /usr/ucb/rlogin is invoked.
# Usage: see rsh(1).

RSH=/usr/ucb/rsh
RLOGIN=/usr/ucb/rlogin

hostname=
lflag=
nflag=
user=

case $1 in
-l)
	;;
*)
	hostname=$1
	shift
esac

case $1 in
-l)
	lflag=-l
	user=$2
	shift 2
esac

case $1 in
-n)
	nflag=-n
	shift
esac

case $hostname in
'')
	hostname=$1
	shift
esac

case $# in
0)
	exec $RLOGIN $lflag ${user+"$user"} "$hostname"
esac

AWK='
	NR > 1 {
		print prev;
		prev = $0;
		prev1 = $1;
		prev2 = $2;
	}
	NR == 1 {
		prev = $0;
		prev1 = $1;
		prev2 = $2;
	}
	END {
		if (prev1 ~ /[0-9]*[0-9]0/)
			exit(prev1 / 10);
		if (prev1 == "0")
			exit(prev2);
		print prev;
		exit(1);
	}
'

exec 3>&1

$RSH "$hostname" $lflag ${user+"$user"} $nflag \
	"(${*-:}); sh -c '"'echo "$0 $1" >&2'\'' $?0 "$status"' \
	2>&1 >&3 3>&- | awk "$AWK" >&2 3>&-
--------------------------- END OF SCRIPT ---------------------------