bin/113860: sh(1): shell is still running when using `sh -c'

Jilles Tjoelker jilles at
Fri Apr 3 14:40:07 PDT 2009

The following reply was made to PR bin/113860; it has been noted by GNATS.

From: Jilles Tjoelker <jilles at>
To: bug-followup at, ed at, olli at,
	freebsd-hackers at
Subject: Re: bin/113860: sh(1): shell is still running when using `sh -c'
Date: Fri, 3 Apr 2009 23:39:05 +0200

 I think this can be improved.
 Given that I've been digging in /bin/sh already...
 Note first that sh already has some of this functionality:
 % sh -c '{ echo a; sleep 10;}&'; sleep 1; ps T
 94682  p9  Ss     0:00.07 zsh
 94702  p9  S      0:00.00 sleep 10
 94704  p9  R+     0:00.00 ps T
 This is the EV_EXIT flag to evaltree() and friends, in eval.c.
 To make this work for '-c', evalstring() needs some flag like EV_EXIT,
 and parsecmd() needs to tell evalstring() that the command it read is
 the last (currently, parsecmd() only reports that there is no command
 anymore; due to the stack-like memory management it is not really
 possible to read ahead a command). Putting "{\n" and "\n}" around the
 string could be an alternative for the latter, as any valid string would
 consist of one (compound) command only.
 The new mode for evalstring() would only be used for '-c' commands when
 '-s' is not given.
 Apart from bash, ksh93 and Solaris /usr/xpg4/bin/sh (which is basically
 ksh88) also treat simple commands in '-c' this way. So I think the idea
 is ok. I'm also slightly annoyed by seeing silly 'sh -c blah' processes
 hanging around, and it is not always possible or desirable to add
 On another note, the EV_EXIT mode is erroneously still used if a trap on
 EXIT has been set (or, maybe, any trap at all; particularly if -T is in
 effect). This means that such traps may not be executed. Most other
 shells seem to do this right.
 Jilles Tjoelker

More information about the freebsd-bugs mailing list