| name | gh-cli-markdown-quoting |
| description | Use when creating or editing a GitHub PR/issue body, comment, or commit message from a shell, or when writing a grep/rg search pattern — especially if the Markdown or pattern contains backticks, `$()`, `>`, or other shell metacharacters that could be expanded before the tool sees them.
|
GitHub CLI Markdown quoting
Overview
Markdown commonly contains backticks, $(), >, and quotes. When that text
passes through a shell as an inline --body "..." argument or an
unquoted/double-quoted heredoc, the shell interprets those characters —
command substitution, redirection — before gh (or rg/grep) ever
sees the string. The result: mangled PR/issue bodies, phantom files created
by stray redirects, or search patterns that silently run commands instead of
matching text.
Verified directly: a double-quoted string containing literal (unescaped)
`@scope.binder_span` and `echo INJECTED` had the first
backtick-span dropped with a "command not found" error and the second
silently replaced by its command's output — the Markdown code spans never
survived. The same string written via a single-quoted heredoc came out
byte-for-byte identical, backticks intact.
The fix
Write the body to a temp file with a single-quoted heredoc delimiter
(<<'EOF', not <<EOF) so the shell never expands its contents, then pass
the file to the tool:
cat > /tmp/pr-body.md <<'EOF'
- Mentions `@scope.binder_span` and runs `moon check` — safe, it's just text now.
EOF
gh pr create --body-file /tmp/pr-body.md
# or: gh pr edit <N> --body-file /tmp/pr-body.md
# or: gh issue create --body-file /tmp/issue-body.md
# or: gh issue comment <N> -F /tmp/issue-comment.md
Prefer a dedicated file-writing tool over a heredoc when one is available —
it writes the exact bytes with no shell involved at all.
Gotchas
Verify after writing
Don't assume a non-error exit means the body rendered correctly — confirm
it:
gh pr view <N> --json body
gh issue view <N> --json body
gh api repos/<owner>/<repo>/issues/comments/<id> --jq .body