| Summary: | /bin/sh problems with grouped pipe and output redir | ||
|---|---|---|---|
| Product: | Base System | Reporter: | Matthias Buelow <mkb> |
| Component: | bin | Assignee: | Tim Robbins <tjr> |
| Status: | Closed FIXED | ||
| Severity: | Affects Only Me | ||
| Priority: | Normal | ||
| Version: | Unspecified | ||
| Hardware: | Any | ||
| OS: | Any | ||
Responsible Changed From-To: freebsd-bugs->tjr This was fixed in NetBSD basesrc/bin/sh/jobs.c revs. 1.44-1.45. I am working on bringing their patch across. State Changed From-To: open->patched Patch committed to HEAD, I will MFC it in a week along with many other shell enhancements. Thanks. State Changed From-To: patched->closed Change has been MFC'd. |
FreeBSD's /bin/sh implementation's got a problem with regard to lists which contain pipes and I/O redirection that applies to the entire list. Please look at the following examples: First an ordinary grouped list with just one command: $ { :; } $ jobs $ and with stdout/err redirected: $ { :; } >/dev/null 2>&1 $ jobs $ now with a pipe instead of a single command: $ { :|:; } $ jobs $ so far everything ok as expected. Now with redirection, it messes up: $ { :|:; } >/dev/null 2>&1 $ jobs [1] 1473 Exit 2 : 1474 Exit 2 : $ This should not happen; the shell should not print any background jobs (there must not be any, since the list is executed synchronously and not even in a subshell.) That wouldn't be so annoying if not, when used in the context of my .profile script (I use /bin/sh for root), it would cause premature end of parsing of said script, resulting in about half of the script not being run at all. I've isolated a test example, which shows a sample premature abort of script parsing (when run in the context of the current shell at least, like it is done with sh reading .profile): cmdinpath() { { type "$1"|grep '/'; } >/dev/null 2>&1 } if cmdinpath less then PAGER=less else PAGER=more fi echo PAGER is $PAGER store into a file "t" and type the following: $ set -o xtrace # doesn't change results, only shows # what the shell is doing $ . ./t + . ./t + cmdinpath less # stops at "if cmdinpath less"... $ echo $? # doesn't even get to the final echo + echo 2 2 $ jobs [1] 1542 Exit 2 type ${1} 1543 Exit 2 grep / $ For comparison, in Korn shell, the script executes properly: $ ksh93 + ksh93 $ . ./t PAGER is less $ jobs $ It also works as expected in the SystemV Bourne shell, ksh88 and pdksh. NetBSD's (1.5.1) /bin/sh, which is also the 4.4BSD ash-derived sh has the same problem. Fix: None yet; I'll perhaps have a look into it. How-To-Repeat: See above.