--- title: "wget/curl: URLs with Special Characters Fail in Bash" domain: troubleshooting category: general tags: [wget, curl, bash, shell, quoting, url] status: published created: 2026-04-08 updated: 2026-04-08 --- # wget/curl: URLs with Special Characters Fail in Bash ## Problem Downloading a URL that contains `&`, `=`, `#`, `?`, or other shell-meaningful characters fails with cryptic errors when the URL is not properly quoted: ```bash wget -O output.mp4 https://cdn.example.com/video%20file.mp4?secure=abc123&token=xyz ``` Bash interprets `&` as a background operator, splitting the command: ``` bash: token=xyz: command not found ``` The download either fails outright or downloads only a partial/error page (e.g., 868 bytes instead of 2 GB). --- ## Root Cause Bash treats several URL-common characters as shell operators: | Character | Shell Meaning | URL Meaning | |---|---|---| | `&` | Run previous command in background | Query parameter separator | | `?` | Single-character glob wildcard | Start of query string | | `#` | Comment (rest of line ignored) | Fragment identifier | | `=` | Variable assignment (in some contexts) | Key-value separator | | `%` | Job control (`%1`, `%2`) | URL encoding prefix | | `!` | History expansion (in interactive shells) | Rarely used in URLs | If the URL is unquoted, Bash processes these characters before `wget` or `curl` ever sees them. --- ## Fix **Always single-quote URLs** passed to `wget` or `curl`: ```bash wget -O '/path/to/output file.mp4' 'https://cdn.example.com/path/video%20file.mp4?secure=abc123&token=xyz' ``` Single quotes prevent **all** shell interpretation — no variable expansion, no globbing, no operator parsing. The URL reaches `wget` exactly as written. ### When to use double quotes instead If the URL contains a shell variable (e.g., a token stored in `$TOKEN`), use double quotes: ```bash wget -O output.mp4 "https://cdn.example.com/file.mp4?secure=${TOKEN}&expires=9999" ``` Double quotes allow variable expansion but still protect `&`, `?`, and `#` from shell interpretation. ### Output filename quoting The `-O` filename also needs quoting if it contains spaces or special characters: ```bash wget -O '/plex/plex/DF Direct Q+A #258.mp4' 'https://example.com/video.mp4' ``` --- ## Quick Reference | Scenario | Quoting | |---|---| | Static URL, no variables | Single quotes: `'https://...'` | | URL with shell variable | Double quotes: `"https://...${VAR}"` | | Output path with spaces | Single or double quotes around `-O` path | | URL in a script variable | Assign with double quotes: `URL="https://..."`, then `wget "$URL"` | --- ## Common Symptoms of Unquoted URLs - `bash: : command not found` — `&` split the command - Download completes instantly with a tiny file (error page, not the real content) - `wget` reports success but the file is corrupt or truncated - `No such file or directory` errors on URL fragments - History expansion errors (`!` in URL triggers `bash: !...: event not found`) --- ## See Also - [Bash Scripting Patterns](../01-linux/shell-scripting/bash-scripting-patterns.md) — general shell quoting and safety patterns