All of lore.kernel.org
 help / color / mirror / Atom feed
* 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.