[comp.bugs.sys5] sh bug

mer6g@virginia.acc.virginia.edu (Marc Rouleau) (10/26/87)

References:


On our 3b2, 3b5, and 3b15 AT&T systems running SYSV.2 and SYSV.3, sh does
something rather unfortunate when certain built-in functions fail.  For
example,

	cd nowhere || echo 'cd failure'

where ``nowhere'' is nonexistent does not (as you might expect) cause ``cd
failure'' to be echoed to the screen.  The expected error message is produced
and then . . . nothing, a new prompt.

This became a problem for us when a cron script which checked for the existence
of a directory in this (admittedly crude) fashion started breaking.  The
script chokes and dies whenever the cd fails.  It seems to happen with other
built-in functions as well; for instance, the ``.'' function does the same
thing when the file given it does not exist.

Luckily, ``test'' works just fine, so we can run around this problem.

BTW, ksh handles all this stuff correctly.

Does anyone have a fix?

-- 
Marc Rouleau		University of Virginia      Academic Computing Center
mer6g@virginia.edu	mer6g@virginia [bitnet]	    	    ...virginia!mer6g

aeusesef@csun.UUCP (sean fagan) (10/28/87)

In article <467@virginia.acc.virginia.edu> mer6g@virginia.UUCP (Marc Rouleau) writes:
>On our 3b2, 3b5, and 3b15 AT&T systems running SYSV.2 and SYSV.3, sh does
>something rather unfortunate when certain built-in functions fail.  For
>example,
>
>	cd nowhere || echo 'cd failure'
>
>where ``nowhere'' is nonexistent does not (as you might expect) cause ``cd
>failure'' to be echoed to the screen.  The expected error message is produced
>and then . . . nothing, a new prompt.
I think that the problem is that cd is a shell built-in, and one of the few
(possibly only?) that doesn't get checked for a return value.  This is a
definitely a bug.  And, as you remark below, it is fixed in Korn Shell.
Fixes would be appreciated here, too.
>BTW, ksh handles all this stuff correctly.

>Marc Rouleau		University of Virginia      Academic Computing Center
>mer6g@virginia.edu	mer6g@virginia [bitnet]	    	    ...virginia!mer6g

 -----

 Sean Eric Fagan          Office of Computing/Communications Resources
 (213) 852 5742           Suite 2600
 1GTLSEF@CALSTATE.BITNET  5670 Wilshire Boulevard
                          Los Angeles, CA 90036
{litvax, rdlvax, psivax, hplabs, ihnp4}!csun!aeusesef

davidsen@steinmetz.UUCP (10/28/87)

In article <467@virginia.acc.virginia.edu> mer6g@virginia.UUCP (Marc Rouleau) writes:
|On our 3b2, 3b5, and 3b15 AT&T systems running SYSV.2 and SYSV.3, sh does
|something rather unfortunate when certain built-in functions fail.  For
|example,
|
|	cd nowhere || echo 'cd failure'

Not all shells have this problem. I tried the Korn shell, "shV" sys V
shell in Xenix, and /bin/sh in a unix-pc. All return bad status when cd
fails. With the exception of ksh, there is no way to determine if the
bug has been fixed in my versions, or your is broken.

Hopefully someone can shed additional light on this.
-- 
	bill davidsen		(wedu@ge-crd.arpa)
  {uunet | philabs | seismo}!steinmetz!crdos1!davidsen
"Stupidity, like virtue, is its own reward" -me

guy@gorodish.UUCP (10/29/87)

> Not all shells have this problem. I tried the Korn shell, "shV" sys V
> shell in Xenix, and /bin/sh in a unix-pc. All return bad status when cd
> fails. With the exception of ksh, there is no way to determine if the
> bug has been fixed in my versions, or your is broken.

I tried "/bin/sh" on a 3B2 running S5R3.1.  The "echo" command is not run.
Thus, the bug must have been fixed in your version, since no version AT&T puts
out as part of their porting base has it fixed.
	Guy Harris
	{ihnp4, decvax, seismo, decwrl, ...}!sun!guy
	guy@sun.com

chris@mimsy.UUCP (Chris Torek) (10/29/87)

The problem: `cd baddir || echo cd failed' does print `baddir: bad
directory', but not `cd failed'.

One workaround:

	(cd baddir) && cd baddir || echo cd failed
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

simon@its63b.ed.ac.uk (Simon Brown) (10/29/87)

In article <467@virginia.acc.virginia.edu> mer6g@virginia.UUCP (Marc Rouleau) writes:
>On our 3b2, 3b5, and 3b15 AT&T systems running SYSV.2 and SYSV.3, sh does
>something rather unfortunate when certain built-in functions fail.  For
>example,
>
>	cd nowhere || echo 'cd failure'
>
>where ``nowhere'' is nonexistent does not (as you might expect) cause ``cd
>failure'' to be echoed to the screen.  The expected error message is produced
>and then . . . nothing, a new prompt.
>

Dat's 'cos the first cd fails, so the shell interrupts itself (well, sort of),
and jumps straight back to command level - without executing the second part of
the "||". What you'll have to do is force the first component to be executed
in a subshell so it can't effect the second - like
	if (cd nowhere)		# cd in a subshell
	then cd nowhere		#  it worked, so cd in the main shell
	else echo 'cd failure'  #  otherwise print error message
  	fi
Of course, you still get the error message from the first cd (if it fails),
unless you redirect it's output elsewhere with
	if (cd nowhere) >/dev/null 2>&1

-- 
----------------------------------
| Simon Brown                    | UUCP:  seismo!mcvax!ukc!{lfcs,its63b}!simon
| LFCS                           | JANET: simon@uk.ac.ed.{lfcs,its63b}
| Department of Computer Science | ARPA:  simon%lfcs.ed.ac.uk@cs.ucl.ac.uk
| University of Edinburgh,       |     or simon%its63b.ed.ac.uk@cs.ucl.ac.uk
| Scotland, UK.                  |     or simon%cstvax.ed.ac.uk@cs.ucl.ac.uk
---------------------------------- 
                      "Life's like that, you know"

billw@igloo.UUCP (Bill Wisner) (11/12/87)

In article <706@its63b.ed.ac.uk> simon@its63b.ed.ac.uk (Simon Brown) writes:
>Dat's 'cos the first cd fails, so the shell interrupts itself (well, sort of),
>and jumps straight back to command level - without executing the second part of
>the "||". What you'll have to do is force the first component to be executed
>in a subshell so it can't effect the second - like
[example using (cd nowhere) deleted]

Sorry, I'm afraid not. Doing a cd in a subshell will do absolutely no good.
The subshell will change directories, but immediately afterwards it will exit,
leaving the original shell back where it started.
-- 
Bill Wisner				..{codas,ihnp4}!ddsw1!igloo!billw
"I don't mind at all.." -- Bourgeois Tagg

allbery@ncoast.UUCP (11/17/87)

As quoted from <318@igloo.UUCP> by billw@igloo.UUCP (Bill Wisner):
+---------------
| In article <706@its63b.ed.ac.uk> simon@its63b.ed.ac.uk (Simon Brown) writes:
| >Dat's 'cos the first cd fails, so the shell interrupts itself (well, sort of),
| >and jumps straight back to command level - without executing the second part of
| >the "||". What you'll have to do is force the first component to be executed
| >in a subshell so it can't effect the second - like
| [example using (cd nowhere) deleted]
| 
| Sorry, I'm afraid not. Doing a cd in a subshell will do absolutely no good.
| The subshell will change directories, but immediately afterwards it will exit,
| leaving the original shell back where it started.
+---------------

Did you *really* look at the example?  It cd's twice.

(cd nowhere) 2> /dev/null && cd nowhere

The first one has no effect -- except that we get an exit status nonzero if
the directory doesn't exist.  This allows (in a klugey way) testing the
exit status of a cd.

Me?  I use ksh.
-- 
Brandon S. Allbery		      necntc!ncoast!allbery@harvard.harvard.edu
{hoptoad,harvard!necntc,{sun,cbosgd}!mandrill!hal,uunet!hnsurg3}!ncoast!allbery
			Moderator of comp.sources.misc