Too long didn't read
Safe characters (literal in/out of quotes):
Troublesome characters (need quoting/escaping):
Table
Character | Not Cause Trouble (Including in Double Quotes) | Will Cause Trouble (Including in Double Quotes) | Reason |
---|---|---|---|
a-z, A-Z |
Yes (literal in or out of quotes) | No | Alphanumeric characters are treated literally by the shell, with no special meaning. |
0-9 |
Yes (literal in or out of quotes) | No | Numeric characters are treated literally, with no special meaning. |
! |
Yes (literal in double quotes, non-interactive shells) | Yes (in interactive shells without quotes or potentially in quotes) | In interactive shells, ! triggers history expansion (e.g., !! becomes the last command). Even in double quotes, it may cause issues if history expansion is enabled. Without quotes, it almost always triggers expansion. |
" |
No (requires escaping or single quotes) | Yes (without quotes, breaks argument) | Without quotes, " starts or ends a quoted string, causing syntax errors. In double quotes, it must be escaped (\" ) to be literal, or it terminates the quote prematurely. |
# |
Yes (literal in double quotes) | Yes (without quotes) | Without quotes, # starts a comment, ignoring the rest of the line. In double quotes, it’s treated literally. |
$ |
No (expands variables without quotes) | Yes (in double quotes if followed by variable name) | $ triggers variable expansion (e.g., $var becomes the variable’s value). In double quotes, it still expands variables (e.g., "$var" ). Without quotes, it always expands if followed by a variable name. |
% |
Yes (literal in or out of quotes) | No | Treated literally, no special shell meaning. |
& |
Yes (literal in double quotes) | Yes (without quotes) | Without quotes, & runs the command in the background, altering execution. In double quotes, it’s literal. |
' |
No (requires escaping or double quotes) | Yes (without quotes, breaks argument) | Without quotes, ' starts or ends a single-quoted string, causing syntax errors. In double quotes, it’s treated literally. |
( |
Yes (literal in double quotes) | Yes (without quotes) | Without quotes, ( starts a subshell, leading to syntax errors if unmatched. In double quotes, it’s literal. |
) |
Yes (literal in double quotes) | Yes (without quotes) | Without quotes, ) ends a subshell, causing errors if unmatched. In double quotes, it’s literal. |
* |
Yes (literal in double quotes) | Yes (without quotes) | Without quotes, * expands to filenames (globbing). In double quotes, it’s literal. |
+ |
Yes (literal in or out of quotes) | No | Treated literally, no special shell meaning. |
, |
Yes (literal in or out of quotes) | No | Treated literally, no special shell meaning. |
- |
Yes (literal in or out of quotes) | No | Treated literally, no special shell meaning. |
. |
Yes (literal in or out of quotes) | No | Treated literally, no special shell meaning (unless part of a command like ./ ). |
/ |
Yes (literal in or out of quotes) | No | Treated literally, used as a path separator. |
: |
Yes (literal in or out of quotes) | No | Treated literally, often used in email:password syntax as a separator. |
; |
Yes (literal in double quotes) | Yes (without quotes) | Without quotes, ; separates commands, altering execution. In double quotes, it’s literal. |
< |
Yes (literal in double quotes) | Yes (without quotes) | Without quotes, < redirects input, causing errors if invalid. In double quotes, it’s literal. |
= |
Yes (literal in or out of quotes) | No | Treated literally, no special shell meaning in arguments. |
> |
Yes (literal in double quotes) | Yes (without quotes) | Without quotes, > redirects output, causing errors if invalid. In double quotes, it’s literal. |
? |
Yes (literal in double quotes) | Yes (without quotes) | Without quotes, ? is a globbing character for single-character matching. In double quotes, it’s literal. |
@ |
Yes (literal in or out of quotes) | No | Treated literally, common in email addresses. |
[ |
Yes (literal in double quotes) | Yes (without quotes) | Without quotes, [ is used for globbing or test commands, causing errors if unmatched. In double quotes, it’s literal. |
\ |
No (escapes next character without quotes) | Yes (in double quotes if escaping special characters) | Without quotes, \ escapes the next character, altering its meaning. In double quotes, it escapes $ , backticks, " , \ , or newline, which may change the string (e.g., \$ becomes literal $ ). |
] |
Yes (literal in double quotes) | Yes (without quotes) | Without quotes, ] closes a globbing or test expression, causing errors if unmatched. In double quotes, it’s literal. |
^ |
Yes (literal in double quotes) | Yes (without quotes in some shells) | In some shells (e.g., zsh), ^ may have special meaning without quotes. In bash, it’s usually literal. In double quotes, it’s always literal. |
` |
No (triggers command substitution without quotes) | Yes (in double quotes) | Backticks trigger command substitution, executing the command inside and inserting its output (e.g., `date` becomes the date). This happens both with and without double quotes, altering the argument. |
_ |
Yes (literal in or out of quotes) | No | Treated literally, no special shell meaning. |
{ |
Yes (literal in double quotes) | Yes (without quotes) | Without quotes, { starts a brace expansion or block, causing errors if unmatched. In double quotes, it’s literal. |
| |
Yes (literal in double quotes) | Yes (without quotes) | Without quotes, | pipes output to another command, altering execution. In double quotes, it’s literal. |
} |
Yes (literal in double quotes) | Yes (without quotes) | Without quotes, } ends a brace expansion or block, causing errors if unmatched. In double quotes, it’s literal. |
~ |
Yes (literal in double quotes unless at start or after : ) |
Yes (without quotes or in double quotes at start/after : ) |
Without quotes, ~ expands to the home directory (e.g., ~ becomes /home/user ). In double quotes, it expands if at the start (e.g., "~user" ) or after a : (e.g., "a:~b" ), potentially altering the argument. |
Space | No (splits arguments without quotes) | Yes (without quotes) | Without quotes, spaces split arguments, causing ./tools to see multiple arguments instead of one. In double quotes, spaces are literal. |
Tab | No (splits arguments without quotes) | Yes (without quotes) | Similar to spaces, tabs split arguments without quotes. In double quotes, tabs are literal. |
Newline | No (ends command without quotes) | Yes (without quotes) | Without quotes, a newline terminates the command, causing errors. In double quotes, newlines are literal but rare in arguments. |