Forcing /bin/sh in a script under V/386 3.2 Korn shell

Jon H. LaBadie jon at jonlab.UUCP
Mon Jul 24 22:10:15 AEST 1989


In article <2318 at wyse.wyse.com>, bob at wyse.wyse.com writes:
	... Much deleted ...
> 
> With respect to the original question of Tom Neff's, perhaps the
> following would help.  It depends on the fact that both _sh_ and
> _ksh_ will execute the similar code, while _ksh_ adds some "extras", such
> as RANDOM, which _sh_ will treat differently.  In _ksh_ each reference
> to RANDOM will cause the value of RANDOM to change.
> 
> 	if [ "$RANDOM" -eq "$RANDOM" ]
> 	then
> 	   # what you want sh to do
> 	else
> 	   # exec sh on this script
> 	   exec /bin/sh `whence $0` "$@"
> 	fi
> 
> The _whence_ builtin generates the full pathname of the current file
> (assuming it is in the path) and _sh_ is used to run it.  The original
> arguments must also be supplied to this new invocation.  Using the quoted
> $@ above (if I understand it correctly), will guarantee that the
> form of the arguments on the original command line will be passed
> to the new script invocation in exactly the same form.

A few comments to strengthen Bob's excellent suggestions:

1. Some shells would generate a fatal error if the arguments supplied
   to the test operator "-eq" were non-numeric.  This is one case
   where the "=" operator might be better on numeric arguments.

2. In case the command being "exec'ed" has a strange name, like "-xyz",
   /bin/sh could still be forced to interpret it as a command with the
   "-c" option.

3. The meaning of "$@" varies with different versions of the shell IF
   there were no arguments on the original command line.  Some properly
   evaluate to no arguments, but some evaluate to one null argument,
   i.e. just like you passed the argument "".  If the program expects
   a file name or no arguments, this can cause problems.

   An alternative solution is a "special substitution" construction.

	${@:+"${@}"}

   This says if $@ is NULL, leave it alone, that is what I want.  But
   if it has a non-NULL value, evaluate to its quoted value.

Combining these comments and using the conditional operator rather than
an if statement; plus quoting $0 on general principles, we have:

  [ "${RANDOM}" = "${RANDOM}" ] || exec /bin/sh -c "${0}" ${@:+"${@}"}

  # what you want sh to do

Now a question for Bob.  Can you let me know the need for the

	`whence $0`

construction in your solution.  On inspection, it seems that $0 would
be sufficient as the script was invoked that way to begin with.  But
I am certain I am overlooking some subtle situation in which that
is not the case.
-- 
Jon LaBadie
{att, princeton, bcr}!jonlab!jon
{att, attmail, bcr}!auxnj!jon



More information about the Comp.unix.questions mailing list