Skip to content

fix: allow escaping operator characters in unquoted words - #186

Merged
bartlomieju merged 2 commits into
mainfrom
fix/escaped-operator-chars
Aug 4, 2026
Merged

fix: allow escaping operator characters in unquoted words#186
bartlomieju merged 2 commits into
mainfrom
fix/escaped-operator-chars

Conversation

@bartlomieju

@bartlomieju bartlomieju commented Aug 3, 2026

Copy link
Copy Markdown
Member

A backslash currently only escapes a fixed set of characters ($, `,
", ~, (, ), and space). The operator characters ;, &, |, < and
> were not in that set, so echo one \; two produced a literal backslash as
one word and then still split the command at the semicolon. Quoting the
character (';' or ";") already worked, so the escape form was silently
doing the wrong thing rather than being unsupported.

This adds those five characters to the set that a backslash can escape in an
unquoted word, which makes the escapable set exactly match the set of
characters that terminate an unquoted word. Inside double quotes those
characters are already literal, so a backslash there keeps its own literal
meaning as it does in POSIX shells, and "a\;b" is unchanged.

A backslash is deliberately not made a general escape the way POSIX specifies,
because that would change the meaning of Windows paths such as
.\node_modules\.bin\x that appear in real tasks. Such a path is only
affected when it ends in a separator that sits directly against an operator,
as in cd .\foo\;echo hi — there the backslash now escapes the ;. Writing
\\ before an operator keeps both backslashes literal and lets the operator
terminate the word, which is what that spelling already did, so the path stays
writable unquoted as cd .\foo\\;echo hi. That carve-out is limited to the
position before an operator, so \\$FOO still escapes the dollar sign.

Closes denoland/deno#36401

A backslash before `;`, `&`, `|`, `<` or `>` now makes the character
part of the word instead of being parsed as an operator, matching what
quoting it already does. Previously `echo one \; two` emitted a literal
backslash and then split the command at the semicolon.

Closes denoland/deno#36401
@peruibeloko

Copy link
Copy Markdown

Thanks for the quick response!

Escaping an operator means a Windows path that ends in a separator and
sits right before an operator (`cd .\foo\;echo hi`) now parses as one
word. Treat `\\` immediately before an operator as two literal
backslashes with the operator still terminating the word, which is what
that spelling already did before the escape existed. The rule is scoped
to that position, so `\\$FOO` keeps escaping the dollar sign.

Also cover an escaped `>` after a file descriptor, a trailing escaped
`&`, and the Windows path cases.
@bartlomieju
bartlomieju merged commit 1514a28 into main Aug 4, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Deno task can't parse commands that use semicolons

2 participants