bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

caller returns wrong line number in command substitution


From: Andrew Neff
Subject: caller returns wrong line number in command substitution
Date: Tue, 18 Oct 2022 17:47:55 +0000

Machine: x86_64
OS: linux-musl
Compiler: gcc
Compilation CFLAGS: -g -O2
uname output: Linux cfa1574b05c7 5.10.102.1-microsoft-standard-WSL2 #1 SMP Wed 
Mar 2 00:30:59 UTC 2022 x86_64 GNU/Linux
uname output: Linux 3beae0f31cdf 5.18.18-100.fc35.x86_64 #1 SMP PREEMPT_DYNAMIC 
Wed Aug 17 16:09:22 UTC 2022 x86_64 Linux
Machine Type: x86_64-pc-linux-musl
Docker: docker run -it --rm bash:5.2

Description:
  Using the "caller" command on a line of bash code in a process substitution 
has been incorrect from bash 3.2 through 5.1, but I could write my code in such 
a way to work around it. Some of these workarounds no longer function in bash 
5.2. I saw that you made some changes to this code [see below], however, I 
think they introduced another regression to how caller calculates the line 
offset. In the following tests, caller should always return the last line in a 
multi-line bash call, but that is not the case now in a process substitution in 
bash 5.2 (test 5)

  [quote]
    c. Rewrote the command substitution parsing code to call the parser 
recursively and rebuild the command string from the parsed command. This allows 
better syntax checking and catches errors much earlier. Along with this, if 
command substitution parsing completes with here-documents remaining to be 
read, the shell prints a warning message and reads the here-document bodies 
from the current input stream

Repeat-By:
  Here's a small script to repeat the problem:

#!/usr/bin/env bash
function foobar()
{
  caller >&2
}
foobar "test0
...
    bar"
true <(foobar "test1
...
    bar")
true <(
  foobar "test2
...
    bar")
true <(\
  foobar "test3
...
    bar")
read -rd '' foo < <(foobar "test4
...
    bar") || :
read -rd '' foo < <(
  foobar "test5
...
    bar") || :
read -rd '' foo < <(\
  foobar "test6
...
    bar")
read -rd '' foo < \
<(foobar "test7
...
    bar")
  Results:

  Test Ans 5.1 5.2
  0    8   8   8
  1    11  13  13
  2    15  18  17
  3    19  21  21
  4    22  22  22
  5    26  26  25
  6    30  29  29
  7    34  33  33

  Summary:
  Test 0: no command substitution, it works.
  Test 1: the answer is off by the number of lines. So 1 line is right, 2 lines 
if off by one line, 3 lines (as show) is off by 2. If it was 10 lines, the 
answer would be off by 9.
  Test 2: Same offset as Test 1. On bash 3.2-5.1 off by one additional line
  Test 3: Same as test 1
  Test 4: Actually right
  Test 5: Off by -1 lines in bash 5.2, right on bash 3.2-5.1
  Test 6: Always off by -1 lines
  Test 7: Same as Test 6

Fix/Workarounds:
  Only the Test0 and Test4 consistently give the right answer. However for 
readability and other reasons, I don't always want those syntaxes.


reply via email to

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