On 14/01/2023 10:57, anonymous4feedback@xxxxxxxxxxx wrote:
Sorry I didn't explain this clearly, and I made some wrong assumption in the first email.
I made another simpler test
# line 1 is empty
# line 2 is empty
foo(){ # line 2
echo $LINENO; } # line 3
foo # line 4
dash prints 2, (line number in function, counting from 1)
bash and ksh prints 4, (line number in whole script)
and zsh prints 1 (line number in function, counting from 0)
More test moving the lines around confirms the guess in parens.
Can I say that none of these is wrong because there is no standard about this?
Hi,
You are correct that dash is setting LINENO to the line number within
the function.
There is a standard about this, but it, in my opinion, is unclear what
the correct behaviour is. It says:
LINENO
Set by the shell to a decimal number representing the current
sequential line number (numbered starting with 1) within a script or
function before it executes each command. [...]
When LINENO appears in a script and a function at the same time, because
the function is within a script, this does not say which of the two is
used as a basis for determining LINENO's value.
There are a few more cases with LINENO that prove problematic, see also
my response to an earlier bug report at
<https://marc.info/?l=dash&m=153725795810101>.
Cheers,
Harald van Dijk
发件人: Marc Chantreux <mc@xxxxxxxxxx>
发送时间: 2023年1月14日 17:39
收件人: anonymous4feedback@xxxxxxxxxxx <anonymous4feedback@xxxxxxxxxxx>
抄送: dash@xxxxxxxxxxxxxxx <dash@xxxxxxxxxxxxxxx>
主题: Re: Bug in dash: Incorrect behaviour of $LINENO in function
hello,
It seems dash stores the line number of the parameter substitution and the line number of the function definition
which is what we expect from a variable expansion. what you need here
is an alias because it works like a minimal but dynamic preprocessor
those are the tricks about aliases:
* they really act as a preprocessor so
alias warn='>&2 echo here at $LINENO'
f() warn first
alias warn='>&2 echo another message at $LINENO'
g() warn last
f;g
# does
here at 1 first
another message at 1 last
* interpolation comes first so
entering() {
echo entering "$@"
"$@"
}
f() echo doing things in functions
alias damn='echo oops ...'
entering f
entering damn
entering f
doing things in functions
entering damn
/home/mc/src/vendor/dash/src/dash: 3: damn: not found
conclusion:
* use functions as long as you can
* in this case, you can't. your solution is
alias warn='>&2 echo here at $LINENO'
HTH,
Marc Chantreux