* Bug in dash: Incorrect behaviour of $LINENO in function
@ 2023-01-14 5:30 anonymous4feedback
2023-01-14 9:39 ` Marc Chantreux
0 siblings, 1 reply; 6+ messages in thread
From: anonymous4feedback @ 2023-01-14 5:30 UTC (permalink / raw)
To: dash
Dear sir or madam,
For the following script,
foo(){ echo $LINENO; }
foo
foo(){
echo $LINENO
}
foo
dash incorrectly prints 2 for the foo on the last line. It seems dash stores the line number of the parameter substitution and the line number of the function definition, and add them to get the result. But the latter is not updated with the function get redefined.
Thanks.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Bug in dash: Incorrect behaviour of $LINENO in function
2023-01-14 5:30 Bug in dash: Incorrect behaviour of $LINENO in function anonymous4feedback
@ 2023-01-14 9:39 ` Marc Chantreux
2023-01-14 10:57 ` 回复: " anonymous4feedback
0 siblings, 1 reply; 6+ messages in thread
From: Marc Chantreux @ 2023-01-14 9:39 UTC (permalink / raw)
To: anonymous4feedback; +Cc: dash
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
^ permalink raw reply [flat|nested] 6+ messages in thread
* 回复: Bug in dash: Incorrect behaviour of $LINENO in function
2023-01-14 9:39 ` Marc Chantreux
@ 2023-01-14 10:57 ` anonymous4feedback
2023-01-14 11:10 ` Harald van Dijk
0 siblings, 1 reply; 6+ messages in thread
From: anonymous4feedback @ 2023-01-14 10:57 UTC (permalink / raw)
To: Marc Chantreux; +Cc: dash
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?
发件人: Marc Chantreux <mc@unistra.fr>
发送时间: 2023年1月14日 17:39
收件人: anonymous4feedback@outlook.com <anonymous4feedback@outlook.com>
抄送: dash@vger.kernel.org <dash@vger.kernel.org>
主题: 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
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: 回复: Bug in dash: Incorrect behaviour of $LINENO in function
2023-01-14 10:57 ` 回复: " anonymous4feedback
@ 2023-01-14 11:10 ` Harald van Dijk
2023-01-14 13:52 ` Marc Chantreux
0 siblings, 1 reply; 6+ messages in thread
From: Harald van Dijk @ 2023-01-14 11:10 UTC (permalink / raw)
To: anonymous4feedback, Marc Chantreux; +Cc: dash
On 14/01/2023 10:57, anonymous4feedback@outlook.com 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@unistra.fr>
> 发送时间: 2023年1月14日 17:39
> 收件人: anonymous4feedback@outlook.com <anonymous4feedback@outlook.com>
> 抄送: dash@vger.kernel.org <dash@vger.kernel.org>
> 主题: 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
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: 回复: Bug in dash: Incorrect behaviour of $LINENO in function
2023-01-14 11:10 ` Harald van Dijk
@ 2023-01-14 13:52 ` Marc Chantreux
0 siblings, 0 replies; 6+ messages in thread
From: Marc Chantreux @ 2023-01-14 13:52 UTC (permalink / raw)
To: Harald van Dijk; +Cc: anonymous4feedback, dash
On Sat, Jan 14, 2023 at 11:10:45AM +0000, Harald van Dijk wrote:
> On 14/01/2023 10:57, anonymous4feedback@outlook.com wrote:
> > Sorry I didn't explain this clearly, and I made some wrong assumption in the first email.
don't be: maybe at just misread you :)
> > 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)
to me, $LINENO should be read as "number of lines from $0" so you can
write
echo error at $0 line $LINE
none of them break this rule AFAIK:
<<\% cat -- > /tmp/pa
S=$1
f() {
echo $S: . $LINENO
}
f
%
<<% xargs -IS sh -c 'S /tmp/a S'
zsh
yash
bash
mksh
$HOME/src/vendor/dash/src/dash
gives
zsh: e . 1
yash: /tmp/a . 3
bash: /tmp/a . 3
mksh: /tmp/a . 3
/home/mc/src/vendor/dash/src/dash: /tmp/a . 2
to me, is the only one problematic here (there is no line 0)
> There is a standard about this, but it, in my opinion, is unclear what the
> correct behaviour is.
as I find the opengroup site (intentionaly?) hard to read, there is the link:
https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html
> 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>.
Sometimes, function overwrite and aliases leads to really simple
and powerful script designs. So after 25 years of shell scripting,
what I think should be standard is:
when inside a function, $0 and $LINENO correspond to
the filename and line number in that file starting from 1
and without any alias expansion.
But I like your conclusion too:
"As for the rest, unless there are strong reasons to go after a
particular result, since POSIX says the results are unspecified,
I would suggest going with whatever is the simplest to implement."
regards
marc
^ permalink raw reply [flat|nested] 6+ messages in thread
* 回复: Bug in dash: Incorrect behaviour of $LINENO in function
@ 2023-01-14 10:55 anonymous4feedback
0 siblings, 0 replies; 6+ messages in thread
From: anonymous4feedback @ 2023-01-14 10:55 UTC (permalink / raw)
Cc: dash
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?
发件人: Marc Chantreux <mc@unistra.fr>
发送时间: 2023年1月14日 17:39
收件人: anonymous4feedback@outlook.com <anonymous4feedback@outlook.com>
抄送: dash@vger.kernel.org <dash@vger.kernel.org>
主题: 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
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2023-01-14 13:52 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-01-14 5:30 Bug in dash: Incorrect behaviour of $LINENO in function anonymous4feedback
2023-01-14 9:39 ` Marc Chantreux
2023-01-14 10:57 ` 回复: " anonymous4feedback
2023-01-14 11:10 ` Harald van Dijk
2023-01-14 13:52 ` Marc Chantreux
2023-01-14 10:55 anonymous4feedback
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.