Subject: piping and suspending shell builtins
To: None <>
From: David Laight <>
List: tech-userlevel
Date: 10/26/2002 19:39:05
The netbsd /bin/sh runs all builtins in the main shell process
unless the output is redirected to a pipe, or is in $(..).

This has two side effects:

1) The output of 'jobs' cannot be fed into a pipeline
   (because it then reports the joblist of the subshell).

2) A shell builtin cannot be suspended (by ^Z) unless it is
   part of such a pipeline.


A subshell environment shall be created as a duplicate of the shell
environment, except that signal traps set by that shell environment shall be
set to the default values.  Changes made to the subshell environment shall
not affect the shell environment.  Command substitution, commands that are
grouped with parentheses, and asynchronous lists shall be executed in a
subshell environment.  Additionally, each command of a multi-command
pipeline is in a subshell environment; as an extension, however, any or all
commands in a pipeline may be executed in the current environment.  All
other commands shall be executed in the current shell environment.

Which implies that 'jobs -p| wc -l' may return the number of jobs,
but is allowed to return zero.
pdksh returns the number of jobs.
I have a (slightly horrid) hack to /bin/sh that will make this work.

The 'obvious' thing is to run the first command of a pipeline from
within the shell process - the 'jobs' will find the correct table.
This made me realize that then, commands like 'env -p|pg' would
not be suspendable.
Checks then confirmed that 'echo' cannot be suspended.

If any commands that are likely to take any length of time are
added as shell builtins, then they ought to be made suspendable.

Even 'echo >some_nfs_fs/file' could take long enough that you might
want to suspend it!

The posix spec says very little about suspending jobs (not where I've
looked anyway).



David Laight: