Created attachment 245417 [details] A sample script for inspiring a fix. The following script reveals the issue 1 #!/bin/sh 2 3 check() 4 { 5 echo $1 - \ 6 $( 7 [ $2 -eq $3 ] \ 8 && echo OK \ 9 || echo FAIL "($2 != $3)" 10 ) 11 } 12 13 main() 14 { 15 check 2 $LINENO 3 16 17 inner() 18 { 19 check 4 $LINENO 3 20 } 21 22 check 3 $LINENO 10 23 inner 24 } 25 26 check 1 $LINENO 26 27 main Here's its output: 1 - OK 2 - OK 3 - FAIL (22 != 10) 4 - OK Every line of the output should be "OK", but the third one fails. The internal logic controlling LINENO seems to ignore that inner() was nested. I attach an ad-hoc "work-around" which could inspire a possible fix.
dash seems to handle this properly.
Was bored and looking for interesting bugs to work on. I tried the script in the body of your message with a few shells. The following tests are all on FreeBSD 14.0. 1. /bin/sh ----------- 1 - OK 2 - OK 3 - FAIL (22 != 10) 4 - OK 2. dash ----------- 1 - OK 2 - OK 3 - OK 4 - OK 3. bash, mksh, ksh93, oksh ----------- 1 - OK 2 - FAIL (15 != 3) 3 - FAIL (22 != 10) 4 - FAIL (19 != 3) What do we think the proper solution to this is?
The interest on having this working on sh is because it's the default root shell in FreeBSD 14.0-RELEASE onwards. And according to its man page and to my best understanding of it the thing should work (on the original post I've attached an ad-hoc "work-around/idea" which could[?] possibly inspire a fix). I know nothing about dash and the other shells. As commented above it seems that dash does not have the issue; great. For the other shells I would suspect they're are all even more flawed WRT $LINENO.