bin/166771: In sh, "local var=$(cat)" only reads one line

Jim Pryor dubiousjim at
Mon Apr 9 01:00:34 UTC 2012

>Number:         166771
>Category:       bin
>Synopsis:       In sh, "local var=$(cat)" only reads one line
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Apr 09 01:00:34 UTC 2012
>Originator:     Jim Pryor
>Release:        9.0-PRELEASE
FreeBSD 9.0-PRERELEASE FreeBSD 9.0-PRERELEASE #0: Tue Nov 29 02:45:33 EST 2011     root at  amd64
I notice the following issue in FreeBSD's /bin/sh, here's the version line from the source:
 * $FreeBSD: src/bin/sh/shell.h,v 2011/09/23 00:51:37 kensmith Exp $

Inside a function, a statement of the form:

  local VAR=$(cat)

will only consume the first line of stdin.

The same problem also afflicts a recent build of dash on Linux, but not Busybox's implementation of ash.

Also reported here: <>.

test1() {
    local IN=$(cat)
    printf "test1 <%s>\n" "$IN"

test1a() {
    local IN
    printf "test1a <%s>\n" "$IN"

test2() {
    local IN="$(cat)"
    printf "test2 <%s>\n" "$IN"

test3() {
    printf "test3 <%s>\n" "$IN"

test4() {
    printf "test4 <%s>\n" "$IN"

MSG=$(printf "abc\ndef\nghi")

printf "%s" "$MSG" | test1
printf "%s" "$MSG" | test1a
printf "%s" "$MSG" | test2
printf "%s" "$MSG" | test3
unset IN
printf "%s" "$MSG" | test4

# The weird bit only shows up in test1:
# IN will only be assigned the first line of stdin.



More information about the freebsd-bugs mailing list