In sh(1), the LINENO variable (currently executed line number) is always zero when it is read as part of a shell arithmetic expression.
$ echo $LINENO $((LINENO)) $(($LINENO))
108 0 108
Expected: 3 times "108" (or whatever the current line number is)
Note that $(($LINENO)) does work because it expands LINENO as a normal shell expansion before invoking the arithmetic subsystem. However, $((LINENO)) should be equivalent as it is for all other variables.
Another manifestation of the bug is:
$ set -u
$ echo $((LINENO))
-sh: arithmetic expression: variable not set: "LINENO"
Created attachment 206211 [details]
Proposed fix patch
This is my first attempt at submitting a patch to FreeBSD. I'm not sure if it's good practice to submit a potential patch directly to the bug report or to first have it reviewed elsewhere such as the mailing lists.
(In reply to Paco Pascal from comment #1)
Proposing patches is always welcome with or without having it discussed or reviewed prior. Having said that, it can and does help, usually to improve the proposed patch, if one can get some feedback on it.
@Jilles (CC'd), with experience in this area of the tree, may know what to do with this
I like that this does not slow down the main execution loop much, since it only does the conversion from integer to string when LINENO is referenced.
This part could be slightly less magic by making a fixed struct var for LINENO (like HISTSIZE, IFS, MAIL, MAILPATH, etc.). This fixed struct can also point to a sufficiently large buffer "LINENO=1\0\0\0\0\0\0\0\0\0\0".
I would like to see this new mechanism used instead of the old VSLINENO mechanism (so there aren't two separate mechanisms for $LINENO and $((LINENO))).
Given that this will subtly change LINENO values anyway (try expanding LINENO twice in different lines of a word spanning multiple lines), I think it would make more sense to make it more like other shells do, reading the line number at the start of a command containing expansions (NCMD/NCASE/NFOR).
With this, it should be possible to set PS4='$LINENO+ ' and see the script's line numbers in set -x output.
You can compare https://git.kernel.org/pub/scm/utils/dash/dash.git/commit/?id=5bb39bb1995cb12d8da76b1d482df9be1acc2eb4 which is a similar implementation for dash (another Almquist variant) but I don't think there will be much benefit in copying code from there.