Should we put file names in Bash in Quotes or Double quotes? What is the standard?

Should we put file names in Bash in Quotes or Double quotes? What is the standard?

SRC=file

or

SRC='file'

or

SRC="file"

?

Asked By: fsgdfgdfgd

||

There is no "standard" according to the Bash Reference Manual.

Variables (Shell parameters):

A variable may be assigned to by a statement of the form

name=[value]

Quoting:

Quoting is used to remove the special meaning of certain characters or
words to the shell. Quoting can be used to disable special treatment
for special characters, to prevent reserved words from being
recognized as such, and to prevent parameter expansion.

On server systems, the default filenames will usually be standard alphanumeric characters, not containing any special characters, and quoting should generally not be needed (although exceptions may apply).

However on desktop systems, it’s more common that filenames contain spaces and other special characters, and then the path should be quoted – and this is generally considered the "safe route".

If quoting, use the quotes that match your needs: Single quotes will treat every single character literally, while double quotes will still treat $, `, and ! as special.

But the criteria for quoting are separate for the syntax of assigning variables, so it entirely depends on the context of the variable (in this case the filename).

Answered By: Artur Meinild

No quotes example:

filePath=Documents Folder 2
echo "$filePath"

This will echo Documents.
Everything after the first space will be lost. You need the quotes in order to retain the spaces. Not using quotes will work for single words only but it’s not considered a good practice in general. It’s better to use quotes anyway.

Double quotes example:

filePath="$HOME/Documents"
echo "$filePath"

This will echo /home/username/Documents

Single quotes example:

filePath='$HOME/Documents'
echo "$filePath" 

This will echo $HOME/Documents

If you want the system to use the characters as they are, use single quotes.
If you want the system to process variables or other special uses, use double quotes.

Answered By: Stormlord

One thing to note about variable assignments is that they are a bit of a special case in shell syntax. From the Bash documentation, in 3.7.1 Simple Command Expansion:

The text after the ‘=’ in each variable assignment undergoes tilde expansion, parameter expansion, command substitution, arithmetic expansion, and quote removal before being assigned to the variable.

In general, however, tokens also undergo field splitting and filename expansion (see 3.5 Shell Expansions), but those are not performed during variable asisgnment.

This means that an unquoted $foo is treated differently in the following cases:

some-command $foo
bar=$foo

Let’s say foo='/* a b c */'. (* a b c * is a perfectly valid name for a directory, so /* a b c */ is a perfectly valid path to a directory.) For some-command $foo, it first becomes as if you’d written:

some-command /* a b c */

And then is expanded by the shell to something like:

some-command /bin /boot ... a b c dir1/ dir2/ ...

But for bar=$foo, that’s not the case. Neither field splitting nor filename expansion will be done, and it will remain as-is – bar will have the value /* a b c */. However, if you then do some-other-command $bar, then it will do field splitting and filename expansion.

In both cases, though, a quoted "$foo" will have the same behaviour:

some-command "$foo" # no field splitting, no filename expansion
bar="$foo"          # equivalent to bar=$foo

Some rules of thumb:

  1. If your value has shell metacharacters, then you will have to quote at least those metacharacters. A metacharacter is:

    A character that, when unquoted, separates words. A metacharacter is a
    space, tab, newline, or one of the following characters: ‘|’,
    &’, ‘;’, ‘(’, ‘)’, ‘<’, or ‘>’.

  2. If the value has !, and history expansion is enabled (which is usually the case in interactive shells), you will need to quote at least the ! using single quotes or a backslash. Double quotes aren’t enough.

  3. If the value has a ~ and you want tilde expansion to happen, then "tilde-prefix" must be unquoted (so ~/ in "/some/path":~/"bar", or ~user/ in ~user/".config/app", etc.). This makes it possible to mix tilde expansion with paths containing spaces and such (so ~user/"some path (with metacharacters)").

  4. If the value has parameter expansions ($foo, ${foo}, etc.), or command substitutions ($(bar), or `foo`), or arithmetic expansions ($((a+b))), or something resembling those, then:

    1. Quote them with single quotes if you don’t want the expansions to be performed. You can also use backslash, but then it’s not sufficient to escape just $ in $(, as ( is a metacharacter as mentioned above and needs to be quoted as well.
    2. Not quoting them is fine if you want them expanded, or you can use double quotes.
  5. If the value has process substitutions (>(...) or <(...)) in it, that will only be performed if the substitution is unquoted.


Arrays are a different game from regular assignment. In general, the part inside (...) for a=(...) is expanded just like it would be anywhere else in the command line, so field splitting and filename expansion are performed. That makes it possible to do something like:

set -f
IFS=:
path=($PATH)

And get entries in $PATH as individual items in the array path.

Answered By: muru

Both will work, although slightly differently. The biggest difference is that between single quotes, most shell expansions (wildcards, variables, command substitution, etc) do not take place, so if your filename contains a variable, such as:

$HOME/Documents/myfile.txt

if you put this in ‘single quotes’ then it will be seen as starting with a literal $ character followed by "HOME" by whatever command/program the filename is sent to. Using "double quotes" allows expansion of variable names (so the above will have $HOME replaced by your actual home directory) but not wildcards, ie * ? [ ] etc. Escaping spaces and other "separator" characters, or closing (single or double) quotes before using the wildcard(s) allows them to work as usual.

On the flip side, if you don’t put filenames or variables supposed to contain filenames in quotes, then anything containing spaces or tabs will be split into several arguments, which is normally not what you want.

Answered By: dolt
Categories: Answers Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.