Subject: Re: sh -c
To: David Laight <david@l8s.co.uk>
From: Greg A. Woods <woods@weird.com>
List: tech-userlevel
Date: 05/01/2003 16:02:18
[ On Thursday, May 1, 2003 at 19:44:49 (+0100), David Laight wrote: ]
> Subject: Re: script command
>
> > A bit far afield but since the common direction seems to be touting
> > POS-ix, one would think that sh knew how to parse options in a similar
> > manner to, or in fact use, getopt(3), and abide by its constructs; i.e.
> > 
> > sh -c -x command -y would (try to) execute "-x", while
> > sh -x -c command -y would (try to) execute "command".
> > 
> > [note that quotes are needed around "command args..." in order to get
> > it to work properly.]
> 
> Indeed our shell does obey posix (since I fixed it a few months ago).
> The synopsis has:
> 
>      sh -c [-aCefnuvxIimqVEb] [+aCefnuvxIimqVEb] [-o option_name]
> 	[+o option_name] command_string [command_name [argument ...]]
> 
> sh -c "command args" will look for a file command\ args, not execute
> command with args.

Are you sure?  The following is from a NetBSD 1.6R installed from a
releng snapshot built on 2003/04/25:

	# sh -c 'echo hello there'
	hello there
	# sh -c 'cat hello there'  
	cat: hello: No such file or directory
	cat: there: No such file or directory

If what you say is what you think POSIX says, then I would say POSIX is
broken w.r.t. the traditional behaviour it should be documenting.

However I think you've mis-interpreted your own implementation!  ;-)

IEEE POSIX Std. 1003.1-2001 says w.r.t. the '-c' form:

     sh -c [-abCefhimnuvx] [-o option] [+abCefhimnuvx] [+o option] command_string [command_name [argument...]]

     The following additional options shall be supported:

     -c
             Read commands from the command_string operand.  Set the
             value of special parameter 0 (see Special Parameters) from
             the value of the command_name operand and the positional
             parameters ($1, $2, and so on) in sequence from the
             remaining argument operands.  No commands shall be read
             from the standard input.

I interpret that to say that "sh -c string" is the same as putting that
string in a file and running it as a script:

	# echo 'echo hello there' > test.script
	# sh test.script
	hello there

Indeed that's how I've always understood 'sh -c', right from V7.

P1003.1-2001 has the added priviso that in the invoked shell the
expansion of $0 will be 'command_name' and $1 will be 'argument', and so
on, but that's a new non-traditional thing as far as I can tell.

The difference being that without the '-c' the command string comes from
the script file specified on the command line, and there is no
"command_name" parameter either as $0 comes from the script name:

	$ uname -r
	1.5W
	$ echo 'echo hello 0=$0 1=$1 2=$2' > test.script
	$ sh ./test.script
	hello 0=./test.script 1= 2=
	$ sh ./test.script foo bar none
	hello 0=./test.script 1=foo 2=bar
	
So, to test for proper 1003.1-2001 conformance of the '-c' form:

	$ uname -r
	1.5W
	$ echo '#! /bin/sh' > test.script
	$ echo 'echo hello 0=$0 1=$1 2=$2' >> test.script
	$ chmod +x test.script           
	$ sh -c ./test.script foo bar none 
	hello 0=test.script 1= 2=

Yup, definitely "broken" as of a year ago....  How about now?

	# uname -r
	1.6R
	# echo '#! /bin/sh' > test.script
	# echo 'echo hello 0=$0 1=$1 2=$2' >> test.script
	# chmod +x test.script           
	# sh -c ./test.script foo bar none
	hello 0=./test.script 1= 2=

Seems to still be "broken".

So I'm not sure what you think you've fixed.

However both current and past behaviour is compatible with /bin/sh on
SunOS-5.6, as well as ksh:

	$ sh -c ./test.script foo bar none                     
	hello 0=./test.script 1= 2=
	$ ksh -c ./test.script foo bar none                    
	hello 0=./test.script 1= 2=
	$ /usr/xpg4/bin/sh -c ./test.script foo bar none
	hello 0=./test.script 1= 2=

So although the NetBSD shell has behaved identically to traditional
implementations both before and after your changes, POSIX defines a new
behaviour (and as yet I can't find a rationale section explaining why).

-- 
								Greg A. Woods

+1 416 218-0098;            <g.a.woods@ieee.org>;           <woods@robohack.ca>
Planix, Inc. <woods@planix.com>; VE3TCP; Secrets of the Weird <woods@weird.com>