stdio/sh behaviour guaranteed?

Giorgos Keramidas keramida at ceid.upatras.gr
Fri Jul 7 22:24:14 UTC 2006


On 2006-07-07 20:23, Jan Grant <jan.grant at bristol.ac.uk> wrote:
> Consider the following snippet.
>
> [[[
> #!/bin/sh
>
> echo one > t
> while read line
> do
>         echo $line
>         case $line in
>         one) echo two >> t
>                 ;;
>         two) echo three >> t
>                 ;;
>         esac
> done <t
> ]]]
>
> This produces three lines of output on FreeBSD: which is what
> I'd intuitively expect and it's certainly useful behaviour.
>
> I'm just trying to determine if that behaviour is one that I
> can rely on - in other words, I guess, if stdio performs a
> "short read" that fails to fill a buffer, and the underlying
> file is then extended outside the process, will another attempt
> to read from the FILE* (or a test of feof, say) honour the new,
> longer file contents?

I think that /bin/sh is not absolutely required to use stdio.h
for input (which could pre-read some text and cause the above to
fail).  Having said that, I think it makes sense to assume that
input is line-buffered, otherwise stuff like this could fail:

    cmd | while read line ; do echo "$line" ; done

> And in particular, is the idiom above blessed by appropriate
> posix standards?

Not sure, but the behavior seems to be the same in Solaris too,
with a variety of shells:

| kobe % cat /etc/release
|                         Solaris 10 1/06 s10x_u1wos_19a X86
|            Copyright 2005 Sun Microsystems, Inc.  All Rights Reserved.
|                         Use is subject to license terms.
|                            Assembled 07 December 2005
| kobe % pwd
| /tmp/t
| kobe % cat -n foo.sh
|      1  #!/bin/sh
|      2
|      3  echo one > t
|      4  while read line
|      5  do
|      6          echo $line
|      7          case $line in
|      8          one) echo two >> t
|      9                  ;;
|     10          two) echo three >> t
|     11                  ;;
|     12          esac
|     13  done <t
| kobe % /bin/sh foo.sh
| one
| two
| three
| kobe % /sbin/sh foo.sh
| one
| two
| three
| kobe % /usr/xpg4/bin/sh foo.sh
| one
| two
| three
| kobe % ksh foo.sh
| one
| two
| three
| kobe % bash foo.sh
| one
| two
| three
| kobe % zsh foo.sh
| one
| two
| three
| kobe %


More information about the freebsd-standards mailing list