Skip to content

pattern: unmatched opening bracket should be treated as a literal #1372

Closed

Description

@kaptinlin

Version: mvdan.cc/sh/v3 v3.13.1

The public pattern.Regexp API rejects an unmatched opening bracket, while Bash treats it as a literal character in shell pattern positions.

To reproduce, create an empty directory and save this as main.go:

package main

import (
	"fmt"

	"mvdan.cc/sh/v3/pattern"
)

func main() {
	regexp, err := pattern.Regexp("[", pattern.EntireString)
	fmt.Printf("regexp=%q error=%T %v\n", regexp, err, err)
}

Run it with:

go mod init example.com/mvdan-repro
go get mvdan.cc/sh/v3@v3.13.1
go run .

Actual output:

regexp="" error=*pattern.SyntaxError [ was not matched with a closing ]

The corresponding Bash pattern matches the literal opening bracket:

case "[" in
	[) echo match ;;
	*) echo miss ;;
esac

Bash output:

match

Would it be appropriate for shell-pattern compilation to treat an unmatched [ as a literal, while retaining errors for malformed constructs that Bash also rejects?

Activity

  1. Pastalikek65 commented on Aug 10, 2026

    @Pastalikek65

    Implemented as PR #1377 — an unmatched [ is now emitted as a literal and the rest of the pattern is reparsed, matching Bash. This also fixes case-statement matching in the interp: case "[" in [) now matches as it does in Bash.

  2. added a commit that references this issue on Aug 11, 2026
    19a6890
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions