Re: sh read on files missing the final newline

наб <[email protected]> Mon, 6 Jul 2026 18:46:56 +0200
Newsgroups gmane.os.netbsd.devel.userlevel
Message-ID <x2o53qdrpnw6utw6xhwnbmcigkabjs7gy3p2ofo7br67z5xfwj@tarta.nabijaczleweli.xyz>
--6wvub7j7bftxqxq6
Content-Type: text/plain; charset=utf-8
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Mon, Jul 06, 2026 at 06:27:01PM +0200, Edgar Fu=C3=9F wrote:
> I stumbled over the fact that sh's read returned 1 on the final part=20
> (call it a line or not) of a file when it didn't end in a newline.
>=20
> Digging through SUS revealed (in the informative part of read):
>=20
> 	Although the standard input is required to be a text file, and=20
> 	therefore will always end with a <newline> (unless it is an empty file)
>=20
> as well as other passages that suggested that a "text file" consists of=
=20
> "lines" and a "line" is a sequence of non-newline characters plus a newli=
ne,=20
> but I couldn't find a definition explicitly stating that.

Poor looking on your part (line numbers from POSIX.1-2024):

1799 3.185 Line
1800 A sequence of zero or more non-<newline> characters plus a terminating=
 <newline> character.

2661 3.387 Text File
2662 A file that contains characters organized into zero or more lines. The=
 lines do not contain NUL
2663 characters and none can exceed {LINE_MAX} bytes in length, including t=
he <newline>
2664 character. Although POSIX.1-2024 does not distinguish between text fil=
es and binary files (see
2665 the ISO C standard), many utilities only produce predictable or meanin=
gful output when
2666 operating on text files. The standard utilities that have such restric=
tions always specify ``text
2667 files=E2=80=99=E2=80=99 in their STDIN or INPUT FILES sections.

And the "final part" is an

1740 3.172 Incomplete Line
1741 A sequence of one or more non-<newline> characters at the end of the f=
ile.

(only ex and sort use this concept at all).


If we're married to the SUS, SUSv1 (Issue 4 Version 2) says much the same t=
hing
(System Interface Definitions Issue 4, Version 2; pp. 19, 30, 18):

line
A sequence of zero or more non-newline characters plus a terminating newlin=
e character.

text file
A file that contains characters organised into one or more lines. The lines=
 must not contain NUL
characters and none can exceed {LINE_MAX} bytes in length, including the ne=
wline character.
Although the XSI does not distinguish between text files and binary files (=
see the ISO C
standard), many utilities only produce predictable or meaningful output whe=
n operating on text
files. The standard utilities that have such restrictions always specify te=
xt files in their STDIN or
INPUT FILES sections.

The term text file does not prevent the inclusion of control or other non-p=
rintable characters
(other than NUL). Therefore, standard utilities that list text files as inp=
uts or outputs are either
able to process the special characters gracefully or they explicitly descri=
be their limitations
within their individual sections. The only difference between text and bina=
ry files is that text
files have lines of less than {LINE_MAX} bytes, with no NUL characters, eac=
h terminated by a
newline character. The definition allows a file with a single newline chara=
cter, but not a totally
empty file, to be called a text file. If a file ends with an incomplete lin=
e it is not strictly a text file
by this definition. The newline character referred to in this document set =
is not some generic line
separator, but a single character; files created on systems where they use =
multiple characters for
ends of lines are not portable to all XSI-conformant systems without some t=
ranslation process.

incomplete line
A sequence of one or more non-newline characters at the end of the file.

(the second para in "text file" is moved to XRAT in POSIX.1-2024)

--6wvub7j7bftxqxq6
Content-Type: application/pgp-signature; name="signature.asc"

-----BEGIN PGP SIGNATURE-----

iQIzBAABCgAdFiEEfWlHToQCjFzAxEFjvP0LAY0mWPEFAmpL2/4ACgkQvP0LAY0m
WPFi5Q/8DHoKOcLHKCSw0A4EWB7L+1jObhey9v7cpdJAf5KITBRa5fggMvmnZCja
0j1Oa47IGDTpb/Atyfx3c+kwkqvH3MAnpAEHN7NBIbobSUavmFiNLPPlqjh83iXb
uIattE47ZKp4PMO9mExSr3KVMVQEZl1irp+q4+w3WA8xL7Z4bC3ahbIfPjNh92OY
zhrU8rqpjALs5nBxIq7umsRNjP2zIpg3D2z76fjnafivNjPOV130jZGpKLQ3HDbK
UjCsMeTCYjVvuwLU/LBCD6NjIknumxY3ifakpPdKyZaeT76t5mer0HUM0RTjhg+F
jxQG7R4d3cuqLXCJbw+E66lLmDWA+LAr5rgJ6ZutxlpWbHUpRJCQfQqcsaLz+e7A
QAs0qelKCyxJWsbk3wJ0ccheO835AXP3Oj0sd83NFQrYy7cvRO/eskklVE4RlbT8
9QHIyGng45KiXjY62E5fDo2g9spZxOAo5hej1N/3Qv8dZayO/zP0ioA+ZKATUWxY
vI+uOjW1PJzfeBqZtyz1G8C6wvO2+RcYg/iQHSQzGpHZiedWa+SS+roPAFJRkN/t
Hvgjzxr7vIQM974Uo2s6P6aDb7SWS/rEe0VRS1zfZlCxp8G1Vd3/v9pB0/kQpMUn
wVwBp4VCcugBZ3OBfPkQ56NlEL50+txoD675LB+FExTcH1gwlOE=
=r5RF
-----END PGP SIGNATURE-----

--6wvub7j7bftxqxq6--