Re: 回复: Bug in dash: Incorrect behaviour of $LINENO in function

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

 



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



[Index of Archives]     [LARTC]     [Bugtraq]     [Yosemite Forum]     [Photo]

  Powered by Linux