For filenames, I know that you have to use either a double quotes or a backslash to include a space in your file name.

Like mkdir "I like coffee" is the same as mkdir I\ like\ coffee

Now when you try to include a $ in your filename, you have to use a backslash

Like mkdir \$dollar

I wonder what other characters other than the space and the dollar sign that I have to use escape characters with when naming my files ?

I found the ? and the * works normal so I was wondering what other characters are like that.

  • That's funny question, but nevertheless the really tricky character in shell is -. Try for example to create such file: touch -, touch '-', touch -- -, touch \- ... nothing works, you need touch ./-.
    – jimmij
    Commented Aug 12, 2015 at 20:19
  • 1
    If I recall, the only illegal characters for a filename are \0 and / -- anything else is allowed. Commented Aug 12, 2015 at 21:49
  • @glennjackman Yep, and it is seriously crazy that the designers did not prohibit \n sigh
    – Ole Tange
    Commented Aug 13, 2015 at 16:10

2 Answers 2


Unix filenames may contain any character (besides '/' or '\0') so this is actually a shell question; the list of metacharacters that need escaping depend on the shell, and the specific configuration of the shell. You appear to be using bash; other shells will fail if the ? or * glob expressions are left unquoted:

$ mkdir test && cd test
$ ls
$ touch *foo
$ ls
$ exec zsh
% touch *bar
zsh: no matches found: *bar
% ls

bash can set the failglob shell option to behave like zsh in this regard. In general, quote everything, or better yet, don't put metacharacters (or even space) into unix filenames, as that path can lead to rm -rf calls nuking entire directory trees, or other random failures (an -i file being read as an argument) or security problems in shell code.


You have not written which shell you are interested in. GNU Parallel quotes any string in ash bash csh dash fdsh fish fizsh ksh ksh93 mksh pdksh posh rbash rc rush rzsh sash sh static-sh tcsh yash zsh. They each need the strings quoted slightly differently. For details see the 'sub shell_quote_scalar' in http://git.savannah.gnu.org/cgit/parallel.git/tree/src/parallel

The core lines are:

  • bash-family: s/[\002-\011\013-\032\#\?`(){}[]\^*\<\=>\~\|\; \"!\$\&\'\202-\377]/\$&/go; s/[\n]/'\n'/go
  • csh-family: s/[\002-\011\013-\032\#\?`(){}[]\^*\<\=>\~\|\; \"!\$\&\'\202-\377]/\$&/go; s/[\n]/"\\n"/go
  • rc: s/'/''/g; s/[\n\002-\011\013-\032\#\?`(){}[]\^*\<\=>\~\|\; \"!\$\&\'\202-\377]+/'$&'/go

For some shells this quotes more characters than is needed for that particular shell, but these characters may need quoting in other shells. E.g. '=' which does not need quoting in bash, but needs it in zsh:

bash$ echo =wc
zsh% echo =wc
zsh% echo \=wc

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .