Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 9 Apr 2012 00:52:04 GMT
From:      Jim Pryor <dubiousjim@gmail.com>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   bin/166771: In sh, "local var=$(cat)" only reads one line
Message-ID:  <201204090052.q390q4PA036033@red.freebsd.org>
Resent-Message-ID: <201204090100.q3910Y4w043546@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>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
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Apr 09 01:00:34 UTC 2012
>Closed-Date:
>Last-Modified:
>Originator:     Jim Pryor
>Release:        9.0-PRELEASE
>Organization:
>Environment:
FreeBSD vaio.jimpryor.net 9.0-PRERELEASE FreeBSD 9.0-PRERELEASE #0: Tue Nov 29 02:45:33 EST 2011     root@vaio.jimpryor.net:/usr/obj/usr/src/sys/MINE  amd64
>Description:
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 1.22.2.1 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: <http://www.mail-archive.com/dash@vger.kernel.org/msg00679.html>.
>How-To-Repeat:
#!/bin/sh

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

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

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

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

test4() {
    IN="$(cat)"
    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.

>Fix:


>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201204090052.q390q4PA036033>