Skip to content

Instantly share code, notes, and snippets.

@pawamoy
Created May 10, 2019 17:24
Show Gist options
  • Save pawamoy/cca35f0f5ccd56665d6421e9b2d2d4bc to your computer and use it in GitHub Desktop.
Save pawamoy/cca35f0f5ccd56665d6421e9b2d2d4bc to your computer and use it in GitHub Desktop.
LINENO in Bash and ZSH
echo $(
# comment
echo "hello" \
"world" \
"thanks" | # comment
cat | ( # comment
# comment
cat -n # comment
) | cat && # comment
echo bye
)
@pawamoy
Copy link
Author

pawamoy commented May 10, 2019

  • Zsh debug output with default PS4:
+script:3> echo hello world thanks
+script:6> cat
+script:8> cat -n
+script:9> cat
+script:10> echo bye
+script:1> echo 1 hello world thanks bye
1 hello world thanks bye
  • Bash debug output with PS4='+$BASH_SOURCE:$LINENO> '
++script:13> echo hello world thanks
++script:14> cat
++script:16> cat -n
++script:17> cat
++script:18> echo bye
+script:11> echo 1 hello world thanks bye
1 hello world thanks bye

Note how the line numbers in Zsh's output are correct, while Bash's line numbers are completely off. In fact, they are not really off, they are offset:

  • the first echo command starts at line 1 but finishes at line 11. It explains the last line of the debug output.
  • then Bash continues to increment the line number from there:
    • line 12 is a comment
    • line 13 is echo hello world thanks
    • but then it starts being unusable, because the previous echo was concatenated, and the offset was not retained, so it continues at 14 for cat, when it should have continued at 16 (in Zsh, echo was at line 3, next cat was at line 6, not line 4). By continuing at 14, it makes calculating the real position using the offset impossible. If it continued at 16, we could have got the correct line number by doing some magic like 16 - 11 + 1 = 6. For this you'd need to know there's an offset of course, which is not trivial either... Here we're left with a 14 that means nothing unless you parse/lex the entire script to understand what's going on.
    • next line, 15, is a comment
    • cat -n at line 16
    • then cat and echo bye, lines 17 and 18

So, these line numbers make sense, but as a shell script writer, when I use a variable that tells me the line number, I expect it to show me the number of the actual line, not an offset increased by one each time a command is ran or a comment is met. It makes debugging even harder, and using debug output impossible in some cases (think coverage).

This, here, could be the main, and single, actual reason for me to finally switch over to Zsh :p

@pawamoy
Copy link
Author

pawamoy commented May 17, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment