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

Jilles Tjoelker jilles at stack.nl
Fri Apr 3 14:39:20 PDT 2009


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
a
  PID  TT  STAT      TIME COMMAND
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
'exec'.

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-hackers mailing list