[comp.unix.questions] \"+\" filename -> /bin/sh !

jl42+@andrew.cmu.EDU (Jay Mathew Libove) (10/19/87)

I tried this as suggested...

*From: Mike Khaw <mkhaw@teknowledge-vaxc.arpa>
*Subject: Re: Trick question
*Date: 17 Oct 87 18:38:05 GMT
*Posted: Sat Oct 17 11:38:05 1987
*To:       info-unix@brl-sem.arpa
*
*+----------
*|>      % cat > +
*|>        date
*|>        ^D
*|>        % chmod +x +
*|>        % +
*|>        $                         -- entered Bourne-shell
*| 
*|       It works for me.  It prints out the date-time.
*+----------
*
*I also get the date printed.  Maybe "which +" will show that somewhere in
*your PATH, "+" is a link to /bin/sh.
*
*Mike Khaw
*-- 
*internet:mkhaw@teknowledge-vaxc.arpa
*usenet:  {uunet|sun|ucbvax|decwrl|uw-beaver}!mkhaw%teknowledge-vaxc.arpa
*USnail:  Teknowledge Inc, 1850 Embarcadero Rd, POB 10119, Palo Alto, CA 94303

... and I end up in /bin/sh also - I checked; there is no file "+"
anywhere on my file system, but if there is a file (regardless of
contents!) anywhere on the path, typing "+" does produce a /bin/sh !
Can anyone explain this, please? This is on SCO Xenix System V r 2
version 2.2.1; Approximately SysVr2, with Berkeley-isms (like having
a csh).

Jay Libove
Arpa:   jl42@andrew.cmu.edu	Bitnet: jl42@drycas.bitnet
UUCP:   ...!{uunet, ucbvax, harvard}!andrew.cmu.edu!jl42
UUCP:   ...!{pitt | bellcore} !darth!libove!libove

Disclaimer: I don't tell my employers what I think...

ken@cs.rochester.edu (Ken Yap) (10/19/87)

Since + is a non-binary, you are effectively doing /bin/sh +.  Try
this:

	/bin/sh +

and get an interactive sh. In fact any argument starting with +
will get you the same result.

My guess is that sh discards arguments starting with + so effectively
you are doing just /bin/sh. This is on SunOS 3.4.

	Ken

gwyn@brl-smoke.ARPA (Doug Gwyn ) (10/19/87)

In article <3351@sol.ARPA> ken@cs.rochester.edu (Ken Yap) writes:
>	/bin/sh +
>and get an interactive sh.

Any Bourne shell that does that is badly broken!

ram%shukra@Sun.COM (Renu Raman, Sun Microsystems) (10/19/87)

In article <3351@sol.ARPA>, ken@cs.rochester.edu (Ken Yap) writes:
> Since + is a non-binary, you are effectively doing /bin/sh +.  Try
> this:
> 
> 	/bin/sh +
> 
> and get an interactive sh. In fact any argument starting with +
> will get you the same result.
> 
> My guess is that sh discards arguments starting with + so effectively
> you are doing just /bin/sh. This is on SunOS 3.4.
> 
> 	Ken


      Following Ken's suggestion, try "cat > -;...." - same result (i.e. 
      a new shell).  Also, try "vi +" and "vi -" as well as 
      "emacs +" and "emacs -" (once you have cretae dthe + & - files).

      Wish we have qizzes/trivia like this more often.
      Maybe  a comp.unix.quiz?

---------------------
   Renu Raman				ARPA:ram@sun.com
   Sun Microsystems			UUCP:{ucbvax,seismo,hplabs}!sun!ram
   M/S 5-40, 2500 Garcia Avenue,
   Mt. View,  CA 94043

mkhaw@teknowledge-vaxc.ARPA (Mike Khaw) (10/19/87)

in article <3351@sol.ARPA>, ken@cs.rochester.edu (Ken Yap) says:
> 
> Since + is a non-binary, you are effectively doing /bin/sh +.  Try
> this:
> 
> 	/bin/sh +
> 
> and get an interactive sh. In fact any argument starting with +
> will get you the same result.
> 
> My guess is that sh discards arguments starting with + so effectively
> you are doing just /bin/sh. This is on SunOS 3.4.
> 
> 	Ken

On Ultrix 1.2, from either /bin/csh or /bin/sh I get:

	+: +: cannot open

On Sun OS 3.4:

	csh% /bin/sh +
	+: Command not found

	sh$ /bin/sh +
	sh$

On Sun OS 3.2, both csh and sh give you a /bin/sh subprocess.

Mike Khaw
-- 
internet:  mkhaw@teknowledge-vaxc.arpa
usenet:	   {uunet|sun|ucbvax|decwrl|uw-beaver}!mkhaw%teknowledge-vaxc.arpa
USnail:	   Teknowledge Inc, 1850 Embarcadero Rd, POB 10119, Palo Alto, CA 94303

gregg@a.cs.okstate.edu (Gregg Wonderly) (10/19/87)

in article <3351@sol.ARPA>, ken@cs.rochester.edu (Ken Yap) says:
> 
> Since + is a non-binary, you are effectively doing /bin/sh +.  Try
> this:
> 
> 	/bin/sh +
> 
> and get an interactive sh. In fact any argument starting with +
> will get you the same result.
> 
> My guess is that sh discards arguments starting with + so effectively
> you are doing just /bin/sh. This is on SunOS 3.4.

I tried

    /bin/sh + +
and
    /bin/csh + +

and got the date command's output from both.  Looks to me like a parsing
error in CSH and SH.

-----
Gregg Wonderly
Department of Computing and Information Sciences
Oklahoma State University

UUCP:  {cbosgd, ihnp4, rutgers}!okstate!gregg
ARPA:  gregg@A.CS.OKSTATE.EDU

stuart@cs.rochester.edu (Stuart Friedberg) (10/19/87)

In article <6583@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) writes:
> In article <3351@sol.ARPA> ken@cs.rochester.edu (Ken Yap) writes:
> >	/bin/sh +
> >and get an interactive sh.
> Any Bourne shell that does that is badly broken!

Ken and I played with this last night.  It is *not* that /bin/sh is
broken.  "+" is treated by sh the same way as "-", as a flag prefix.
(See the section of the manual on "set".) When, after processing a list
of flags, it finds no arguments left it (by default) starts an
interactive shell.  That is, "/bin/sh +" behaves just like "/bin/sh".

We can explain the originally posted behavior as an interaction of
several features.  First note the odd scenarios (they really happen):

1)		2)		3)
csh% +		csh% + +	csh% + date
$		<the date>	date: date: not found

4)		5)		6)
sh$ +		sh$ + +		sh$ + date
<the date>	<the date>	<the date>

Notice that in all cases, /bin/sh does the expected thing.  So, the
problem is in the interaction of csh, exec, and sh.

(1) Csh execs "+".  The kernel finds no good magic number, so actually
execs a /bin/sh giving it an argument list of "/bin/sh", "+".  The sh
parses its arguments, finds nothing left after processing the flags,
and (by default) becomes an interactive shell.

(2) Csh execs "+". The kernel ... giving it an argument list of
"bin/sh", "+", "+".  The sh parses its arguments, *apparently*
treats "+" exactly as a solitary "-", and treats the second "+"
as a script name.  It spawns a subSHELL with argument list
"sh", "-i" to process "+".

(3) Csh execs "+".  The ... list of "/bin/sh", "+", "date".  The sh ...
spawns a subSHELL with arg list "sh", "-i" to process "date", which
can not be found in the current directory.  Hence the error.  Note
the subshell identifies itself as "date" rather than "sh".

(4-6) Sh execs "/bin/sh" with arglist "sh", "-i" to process "+" and its
various arguments.  Because the shell is set up to do interactive
processing, the name of the "input" file is not subject to command line
processing.  The interesting question is how sh detects that "+" should
be processed as a script, because it is clearly not execing "+".  Does
it check for magic numbers before calling exec?  (I suppose)

Stu Friedberg  stuart@cs.rochester.edu

kyle@xanth.UUCP (Kyle Jones) (10/20/87)

In article <6583@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) writes:
> In article <3351@sol.ARPA> ken@cs.rochester.edu (Ken Yap) writes:
> >	/bin/sh +
> >and get an interactive sh.
> 
> Any Bourne shell that does that is badly broken!

Not necessarily.  The use of '+' as a command line argument to the
Bourne shell is documented, at least in Sun OS 3.4 .  It works in the
oppositely manner of '-'; '-' turns on options, '+' turns them off.

Yes, logically '+' should turn on options but it's FAR too late to
change something like that now.

kyle jones  <kyle@odu.edu>  old dominion university, norfolk, va  usa

avolio@decuac.dec.com (Frederick M. Avolio) (10/20/87)

In article <18062@teknowledge-vaxc.ARPA> mkhaw@teknowledge-vaxc.ARPA (Mike Khaw) writes:
>in article <3351@sol.ARPA>, ken@cs.rochester.edu (Ken Yap) says:

>> Since + is a non-binary, you are effectively doing /bin/sh +.  Try
>> this:
>> 	/bin/sh +
>> 
>> and get an interactive sh. In fact any argument starting with +
>> will get you the same result.
>On Ultrix 1.2, from either /bin/csh or /bin/sh I get:
>
>	+: +: cannot open
>

I am not sure what all the hubbub (haven't used THAT one in awhile,
eh?) is all about but it all depends on how arguments to the
particular shell are handled and what version of the shell, etc.  For
example, the System V r 2 Bourne Shell that comes with ULTRIX-32
(/bin/sh5) does indeed start up a subshell on your terminal as
originally discribed. 

The reason is that a '+' is allowed, similar to a '-' to turn on some
flags (see the manual page).  It goes into a piece of code which
affectively says:

	"sh +"
	Hmmmm...  let's parse those arguments...
		I see a '+'.  Let's go into a while loop, 
		turning on options as we go
			while options -- oops, no more options, bailout
		Now, for more arguements... Oh, no more. Drop through.
	Ok, I am ready... no file name so read from the tty

Now, admittedly, I am not sure that this is a Good Thing, but this is
*why* it happens and does not happen on all shells.  Depends on *which*
Bourne shell it is (v7?  SysVr2.0?  2.2?  SysVr3?) and how it is
written.

Fred

schaefer@ogcvax.UUCP (Barton E. Schaefer) (10/20/87)

In article <sol.3375> stuart@cs.rochester.edu (Stuart Friedberg) writes:
}In article <6583@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) writes:
}> In article <3351@sol.ARPA> ken@cs.rochester.edu (Ken Yap) writes:
}> >	/bin/sh +
}> >and get an interactive sh.
}> Any Bourne shell that does that is badly broken!
}
}Ken and I played with this last night.  It is *not* that /bin/sh is
}broken.  "+" is treated by sh the same way as "-", as a flag prefix.
}(See the section of the manual on "set".) When, after processing a list
}of flags, it finds no arguments left it (by default) starts an
}interactive shell.  That is, "/bin/sh +" behaves just like "/bin/sh".
}
} [ Lengthy explanation of what may be happening, including 6 sub-cases,
}   mercifully deleted :) ]

Recall that the original query began with the equivalent of
	echo date > + ; chmod +x + ; +
which for unknown reasons produced an interactive /bin/sh.

I tried the 3 "broken" csh-related subcases that Stuart listed, plus a few
other combinations, on our VAX 11/780 4.3 BSD.  Every one of them produced
the date as output, though some took significantly longer to do so than others.
The slowest one was "csh +", probably because it was reading my .cshrc file.

All this goes to show is that all UN*Xs are not created equal.  Stuart and Ken
are very probably correct about what is happening on their system, but it
doesn't hold true everywhere.

My question is, which of these behaviors (those described by Stuart & Ken, or
the more "expected" behavior that I found) is "correct"?

-- 
Bart Schaefer			CSNET:	schaefer@cse.ogc.edu
				UUCP:	...{tektronix,verdix}!ogcvax!schaefer
"It could have been worse.  I could have woken up and been Robert Bork."
	    -- Joe Garagiola, after his broadcast partner angered Twins fans

ron@topaz.rutgers.edu (Ron Natalie) (10/21/87)

This is a bug with the CSH on certain system V machines.  If this
bug ever existed in 4 BSD, it went away a long time ago.  CSH on
these machines (including the UNISOFT system V I have) will do
"/bin/sh +" when you try to execute "+" and it is not a kernel
executable.

It is not:
    1.  Any bug in the Bourne Shell.  Doug Gwyn made the comment
        that no working Bourne Shell would execute the shell when
	you type "+" at it, which is true.  However, the cshell
	is interpretting the script as "/bin/sh +"

    2.  It is not a bug in the kernel.  The kernel is correctly
	returning an error because this file is not executable
	as far as it is concerned.

    3.  A bug that will show up in any modern release of BSD operating
	systems (including those on the SUN), so all you BSD users
	can stop telling us that there is no bug.

-Ron

batson@cg-atla.UUCP (Jay Batson X5927) (10/21/87)

In article <18062@teknowledge-vaxc.ARPA> mkhaw@teknowledge-vaxc.ARPA (Mike Khaw) writes:
>in article <3351@sol.ARPA>, ken@cs.rochester.edu (Ken Yap) says:
>> 
>> Since + is a non-binary, you are effectively doing /bin/sh +.  Try
>> this:
>> 	/bin/sh +
>> and get an interactive sh. In fact any argument starting with +
>> will get you the same result.
>> 
>> My guess is that sh discards arguments starting with + so effectively
>> you are doing just /bin/sh. This is on SunOS 3.4.
>> 
>> 	Ken
>On Ultrix 1.2, from either /bin/csh or /bin/sh I get:
>	+: +: cannot open
>On Sun OS 3.4:
>	csh% /bin/sh +
>	+: Command not found
>	sh$ /bin/sh +
>	sh$
>On Sun OS 3.2, both csh and sh give you a /bin/sh subprocess.


Does the fact that things are working this way on the Sun and not on Ultrix
mean anything?  I haven't followed this discussion closely, but have
persons BESIDES Sun users found this to work?

The reason I ask is that Sun has provided us with "Yellow Pages" so
we can all login across networks and have one passwd file.  Note that
on clients, the last entry begins with a '+'.  The recommended rest-of-
entry leaves most fields blank.  Note that the passwd(5) indicates that
a blank "shell" field means /bin/sh by implication.

Now I haven't looked at src to see, but might /bin/sh be finding client
yellow pages passwd file entries and executing the shell?


(Yes, I know it's a stretch, but I haven't posted anything in a while,
and I wanted to "see my name in print").


Jay Batson

mack@inco.UUCP (Dave Mack) (10/22/87)

In article <18062@teknowledge-vaxc.ARPA>, mkhaw@teknowledge-vaxc.ARPA (Mike Khaw) writes:

> On Sun OS 3.4:
> 
> 	csh% /bin/sh +
> 	+: Command not found
> 
> 	sh$ /bin/sh +
> 	sh$
> 

When csh is given the text file, it checks the first character of the
file to see if it's '#'. If not, it hands the file off to /bin/sh.

/bin/sh interprets a '+' or '-' on the command line as an attempt to
set or reset a flag. It apparently ignores an absent or unrecognized
flag silently. Having used up its argv, it thinks it was invoked
without arguments, so it lights up interactively.

If the file named "+" contains:

# comment
date
[EOF]

the + command works as expected.



-- 
  		Dave Mack	The Lord of the Files
  McDonnell Douglas-Inco, Inc. 		DISCLAIMER: The opinions expressed
  8201 Greensboro Drive                 are my own and in no way reflect the
  McLean, VA 22102			views of McDonnell Douglas or its
  (703)883-3911				subsidiaries.
  {uunet | sundc | rlgvax | netxcom | decuac}!hadron!inco!mack
8============================================================================)

ejw@sask.UUCP (Eric Woodsworth) (10/27/87)

> 
> in article <3351@sol.ARPA>, ken@cs.rochester.edu (Ken Yap) says:
>> 
>> Since + is a non-binary, you are effectively doing /bin/sh +.  Try
>> this:
>> 
>> 	/bin/sh +
>> 
>> and get an interactive sh. In fact any argument starting with +
>> will get you the same result.
>> 
>> My guess is that sh discards arguments starting with + so effectively
>> you are doing just /bin/sh. This is on SunOS 3.4.
>> 
>> 	Ken
> 
> On Ultrix 1.2, from either /bin/csh or /bin/sh I get:
> 
> 	+: +: cannot open
> 
> On Sun OS 3.4:
> 
> 	csh% /bin/sh +
> 	+: Command not found
> 
> 	sh$ /bin/sh +
> 	sh$
> 
> On Sun OS 3.2, both csh and sh give you a /bin/sh subprocess.
> 
> Mike Khaw

I asked wylie@sask.UUCP what his opinion was on all this and he came up
with the following explanation, which I think sheds more light than the
past responses to date.
======================================================================

Date: Mon, 26 Oct 87 12:18:04 cst
From: wylie@sask.UUCP (Kelly Wylie)
Message-Id: <8710261818.AA24575@sask.USask.UUCP>
To: zeus@pmbrc.UUCP
Subject: Re:  trick

I tried it on kim (4.2 BSD) and skorpio (Pyramid) in both ucb and att mode.
On kim and skorpio in ucb mode (i.e. 4.2 based) it behaved the same as 
on max - the date resulted from both.  However in att mode (System V based)
I got the behavior described in the message.  As near as I can figure out,
"+" is not a special character for 4.2 based sh.  It is a special charater
for System V based sh.  Below is the section on the set command for both
the System V sh and the BSD sh.  Note the marked difference.  
I also noticed that there was a "/bin/sh +" visible when I did a ps in the
att world with the sh running.  I think what is happening is the following.
When a command is given the csh looks at the file and determines that it
is a shell script.  Since the first few characters are not "#!" it forks
a Bourne shell and gives the name of the file as the argument with the intention
that the sh would execute the contents of the file.  Up to this point it is
the same for both att and ucb worlds.  The difference occurs when the sh
looks at its arguments.  In the ucb world, the "+" is not a special character
so it proceeds as expected, i.e. it executes the contents of the file.  In the
att world, the sh sees the "+" argument and thinks that it is a shell argument
rather than a file name, so it invokes an interactive sh.  It never looks at
the contents of the file.

ATT sh
------
          set [ --ekntuvx [ arg ... ] ]
               -e   Exit immediately if a command exits with a non-
                    zero exit status.
               -k   All keyword arguments are placed in the
                    environment for a command, not just those that
                    precede the command name.
               -n   Read commands but do not execute them.
               -t   Exit after reading and executing one command.
               -u   Treat unset variables as an error when
                    substituting.
               -v   Print shell input lines as they are read.
               -x   Print commands and their arguments as they are
                    executed.
               --   Do not change any of the flags; useful in setting
                    $1 to -.
-------->>     Using + rather than - causes these flags to be turned
               off.  These flags can also be used upon invocation of
               the shell.  The current set of flags may be found in
               $-.  The remaining arguments are positional parameters
               and are assigned, in order, to $1, $2, ....  If no
               arguments are given then the values of all names are
               printed.

UCB sh
------
     set [-eknptuvx [arg ...]]
          -e If non interactive, exit immediately if a command
             fails.
          -k All keyword arguments are placed in the environment
             for a command, not just those that precede the com-
             mand name.
          -n Read commands but do not execute them.
          -t Exit after reading and executing one command.
          -u Treat unset variables as an error when substituting.
          -v Print shell input lines as they are read.
          -x Print commands and their arguments as they are exe-
             cuted.
          -  Turn off the -x and -v options.

          These flags can also be used upon invocation of the
          shell.  The current set of flags may be found in $-.

          Remaining arguments are positional parameters and are
          assigned, in order, to $1, $2, etc.  If no arguments
          are given, the values of all names are printed.



Kelly

zap@draken.UUCP (10/31/87)

In article <968@cg-atla.UUCP> batson@cg-atla.UUCP (Jay Batson X5927) writes:
>Does the fact that things are working this way on the Sun and not on Ultrix
>mean anything?  I haven't followed this discussion closely, but have
>persons BESIDES Sun users found this to work?
[ Speculations whether YP has anything to with this, alluding to the
  /etc/passwd entry "+" used on YP-clients, deleted ]

Yes it is significant that this "works" on Sun (actually SunOS 3.2 or
higher) and SystemV, but not on BSD-derived systems (other than Sun).
The reason? In SunOS 3.2 and higher /bin/sh is the SystemV.2 Bourne
shell.

On the Pyramid the trick works in the att universe but not in the
bsd universe.

The original poster of the question posted it from a Sun running SunOS 3.2

Svante Lindahl		zap@nada.kth.se

guy%gorodish@Sun.COM (Guy Harris) (11/01/87)

> In SunOS 3.2 and higher /bin/sh is the SystemV.2 Bourne shell.

SunOS 3.0 and higher, not just 3.2 and higher.
	Guy Harris
	{ihnp4, decvax, seismo, decwrl, ...}!sun!guy
	guy@sun.com