bug-bash
[Top][All Lists]
Advanced

[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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]