Skip to content

jsh: tail command's -n does not treat - or + in the -n argument correctly #2158

Description

@dantman

Describe the bug

In the webcontainer terminal the tail commands -n argument does not behave like tail -n [-/+]# in POSIX does when you include a symbol before the number:
https://www.man7.org/linux/man-pages/man1/tail.1p.html

-c number The application shall ensure that the number option-
         argument is a decimal integer, optionally including a
         sign.  The sign shall affect the location in the file,
         measured in bytes, to begin the copying:
            ┌──────┬────────────────────────────────────────┐
            │ Sign │             Copying Starts             │
            ├──────┼────────────────────────────────────────┤
            │  +   │ Relative to the beginning of the file. │
            │  -   │ Relative to the end of the file.       │
            │ none │ Relative to the end of the file.       │
            └──────┴────────────────────────────────────────┘

         The application shall ensure that if the sign of the
         number option-argument is '+', the number option-
         argument is a non-zero decimal integer.

         The origin for counting shall be 1; that is, -c +1
         represents the first byte of the file, -c -1 the last.

-n number This option shall be equivalent to -c number, except the
         starting location in the file shall be measured in lines
         instead of bytes. The origin for counting shall be 1;
         that is, -n +1 represents the first line of the file, -n
         -1 the last.

Link to the blitz that caused the error

https://stackblitz.com/edit/vitejs-vite-evjt7z7u?file=README.md&view=editor

Steps to reproduce

  1. Open a webcontainer like https://stackblitz.com/edit/vitejs-vite-evjt7z7u?file=README.md&view=editor
  2. Create a test.txt file
    first 1
    first 2
    last 9
    last 8
    last 7
    last 6
    last 5
    last 4
    last 3
    last 2
    last 1
    
  3. Run the following commands:
    a.
    # No symbol: Relative to the end of the file.
    tail -n 2 test.txt
    b.
    # negative symbol: Relative to the end of the file.
    tail -n -2 test.txt
    c.
    # positive symbol: Relative to the beginning of the file.
    tail -n +2 test.txt

In webcontainers you will get the result:

❯ # No symbol: Relative to the end of the file.
❯ tail -n 2 test.txt
last 2
last 1

❯ # negative symbol: Relative to the end of the file.
❯ tail -n -2 test.txt
tail: illegal offset -- -2

❯ # positive symbol: Relative to the beginning of the file.
❯ tail -n +2 test.txt
last 2
last 1

Expected behavior

❯ # No symbol: Relative to the end of the file.
❯ tail -n 2 test.txt
last 2
last 1
❯ # negative symbol: Relative to the end of the file.
❯ tail -n -2 test.txt
last 2
last 1
❯ # positive symbol: Relative to the beginning of the file.
❯ tail -n +2 test.txt
first 2
last 9
last 8
last 7
last 6
last 5
last 4
last 3
last 2
last 1

Additional context

I was experimenting in StackBlitz with what would happen if I tried building PostHog's ANTLR grammar with https://www.antlr-ng.org/.

PostHog's package.json is "grammar:build:cpp": "cd posthog/hogql/grammar && cat HogQLLexer.cpp.g4 > HogQLLexer.g4 && tail -n +2 HogQLLexer.common.g4 >> HogQLLexer.g4 && antlr -o ../../../common/hogql_parser -Dlanguage=Cpp HogQLLexer.g4 && rm HogQLLexer.g4 && antlr -o ../../../common/hogql_parser -visitor -no-listener -Dlanguage=Cpp HogQLParser.g4", and I got tripped up when cat HogQLLexer.cpp.g4 > HogQLLexer.g4 && tail -n +2 HogQLLexer.common.g4 >> HogQLLexer.g4 did not behave as it should in StackBlitz.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions