Skip to content

Instantly share code, notes, and snippets.

@susovanpanja
Created November 15, 2018 08:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save susovanpanja/c113f035b93fc7a2abf5b5e7713a817e to your computer and use it in GitHub Desktop.
Save susovanpanja/c113f035b93fc7a2abf5b5e7713a817e to your computer and use it in GitHub Desktop.
The following characters have special meaning to the shell itself in some contexts and may need to be escaped in arguments:
` Backtick (U+0060 Grave Accent)
~ Tilde (U+007E)
! Exclamation mark (U+0021)
# Hash (U+0023 Number Sign)
$ Dollar sign (U+0024)
& Ampersand (U+0026)
* Asterisk (U+002A)
( Left Parenthesis (U+0028)
) Right parenthesis (U+0029)
 (⇥) Tab (U+0009)
{ Left brace (U+007B Left Curly Bracket)
[ Left square bracket (U+005B)
| Vertical bar (U+007C Vertical Line)
\ Backslash (U+005C Reverse Solidus)
; Semicolon (U+003B)
' Single quote / Apostrophe (U+0027)
" Double quote (U+0022)
↩ New line (U+000A)
< Less than (U+003C)
> Greater than (U+003E)
? Question mark (U+003F)
  Space (U+0020)1
Some of those characters are used for more things and in more places than the one I linked.
There are a few corner cases that are explicitly optional:
! can be disabled with set +H, which is the default in non-interactive shells.
{ can be disabled with set +B.
* and ? can be disabled with set -f or set -o noglob.
= Equals sign (U+003D) also needs to be escaped if set -k or set -o keyword is enabled.
Escaping a newline requires quoting — backslashes won't do the job. Any other characters listed in IFS will need similar handling. You don't need to escape ] or }, but you do need to escape ) because it's an operator.
Some of these characters have tighter limits on when they truly need escaping than others. For example, a#b is ok, but a #b is a comment, while > would need escaping in both contexts. It doesn't hurt to escape them all conservatively anyway, and it's easier than remembering the fine distinctions.
If your command name itself is a shell keyword (if, for, do) then you'll need to escape or quote it too. The only interesting one of those is in, because it's not obvious that it's always a keyword. You don't need to do that for keywords used in arguments, only when you've (foolishly!) named a command after one of them. Shell operators ((, &, etc) always need quoting wherever they are.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment