3

When I do something like this:

x="hi echo hello"

or

x='hi echo hello'

Then x will contain the string hi echo hello.

But when I don't use quotes:

x=hi echo hello

Then x will contain the string hi, and the command echo hello will be executed.


But what about when a variable's value only consists of a single word, is there a difference between the following:

x="hi"
x='hi'
x=hi
ilkkachu
  • 138,973

3 Answers3

2

Only if the world contains substitutions.

So

x=$FRED

is different from:

x='$FRED'
Julian
  • 549
  • 2
    not only variables. also for other shell metacharacters. e.g. x='()' (literal string) is not the same as x=() (define x as an empty array). quotes aren't always required but it's a good habit to always quote the RHS of assignments - single quotes for literal, static values. and double-quotes for interpolated values. – cas Jan 01 '18 at 13:23
  • and of course x=cat is very different from x=\cat``. – Julian Jan 01 '18 at 13:33
1

No, plain letters and numbers don't change in meaning if they are quoted or not.

Also, as mentioned in this answer, neither word splitting after an expansion, or filename globbing happen when doing an assignment, so the glob characters are not special in that context, and unlike most other places, you can use unquoted variables without invoking splitting. var1=* assigns the literal asterisk, and var2=$var1 assigns the value of var1, regardless of any IFS characters in it.

Other special characters are still special:

  • whitespace
  • $ and backticks ` used for expansions (as @Julian noted)
  • parenthesis, which are used for array assignment (as @cas noted). They will cause a syntax error if misplaced
  • ! for history expansion, <>| for redirections, ; and & that end pipelines, and backslashes \ that escape other characters.

All of those need to be either quoted or escaped to prevent their special meaning.

ilkkachu
  • 138,973
  • Note that you can quote parts of a string, or switch between different kinds of quotes, and the quoting affects only the parts within the quotes. For instance, all of these of exactly the same thing: x="hi echo hello" (entire string double-quoted), x=hi" "echo' 'hello (just the spaces quoted, one with single- and one with double-quotes), and x="h"i" "e'c'ho\ h"ello" (random sections quoted including first space, second space escaped). Since the letters don't have any special meaning to the shell, it doesn't matter whether they're quoted or not. – Gordon Davisson Jan 01 '18 at 22:35
1

The first thing that the shell does it to split the line on unquoted spaces (metacharacters) into tokens. This is different than the word-splitting done after expansions in that the IFS value is not used. The characters used for initial token splitting are fixed as metacharacters. All this will make var contain Hello (sometimes for a brief moment):

var=Hello echo World       # Space
var=Hello;echo World       # Semicolon
var=Hello   echo World     # Tab
var=Hello&echo World       # Ampersand

Also, for this initial token splitting, the right side of an assignment is considered quoted.
All this are equivalent:

var="Hello World"
var='Hello World'
var=Hello\ World

Note that the only character that must be quoted is the white space. Even if IFS is modified.

Of course, inside double quotes several expansions are allowed:

var=~"/"       ;  var=~/         tilde  expansion (outside quotes)
var="$PWD"     ;  var=$PWD       parameter  and variable expansion
var="$(pwd)"   ;  var=$(pwd)     command substitution
var="$((2+3))" ;  var=$((2+3))   arithmetic expansion
var="!$"       ;  var=!$         history substitution

All pairs above are equivalent (the same).

None of the pairs will work the same inside single quotes (or with some back-quotes), example:

var='$PWD'     ;  var=\$PWD

Also, this are not equivalent:

var="( Hello World )"   ; var=( Hello World )

The parenthesis trigger an array assignment


So, all this are equivalent:

var=hi
var="hi"
var='hi'
var=\hi
var=h\i
var=\h\i

taking into account the special conditions given previously.