[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: 5.1 regression?
From: |
Dominique Martinet |
Subject: |
Re: 5.1 regression? |
Date: |
Mon, 1 Aug 2022 16:37:18 +0900 |
Harald Dunkel wrote on Mon, Aug 01, 2022 at 09:08:40AM +0200:
> a colleague pointed me to a changed behavior of bash 5.1.4 in Debian 11.
> Would you mind to take a look at this code?
>
> ----
> #! /bin/bash
> # set -x
>
> insert()
> {
> local data="$1"
> local lineNumber="$2"
>
> head -n "$lineNumber"
The problem is that stdin is eaten up by this head command.
What changed is that bash used to store stdin input in a temporary file,
so head could seek back to the actual position in the stream after the
first three lines but that no longer works:
1007746 read(0, "this is line one\nthis is line two\nthis is line three\nthis
is line four\nthis is line five\nthis is line six\nthis is line seven\n", 8192)
= 125
1007746 lseek(0, -72, SEEK_CUR) = -1 ESPIPE (Illegal seek)
In bash 5.0 0 here was a temporary file in /tmp, and that lseek worked,
but you cannot rely on that in general -- splitting stdin is difficult
business...
You'll get the same behaviour back if you go through a temporary file
again e.g. (don't actually do that!!)
----
echo "$text" > /tmp/temp
output="$( insert "Hello" 3 < /tmp/temp )"
rm /tmp/temp
----
Now as for how to actually do this, tough question. If your example is
representative of your real text you can just use awk or any other
single command:
----
insert()
{
local data="$1"
local lineNumber="$2"
awk -v lineno=$lineNumber -v data="$data" \
'{ print }
NR == lineno {
print "blabla", data
}'
}
----
--
Dominique