19

In shell scripting, what is the difference between these two when assigning one variable to another:

a=$b

and

a="$b"

and when should I use one over the other?

codeforester
  • 39,467
  • 16
  • 112
  • 140
John
  • 301
  • 2
  • 5
  • Related post on U&L Stack Exchange: [Are quotes needed for local variable assignment?](https://unix.stackexchange.com/a/97569/201820). – codeforester May 24 '18 at 22:19

5 Answers5

8

I think there is no big difference here. Yes, it is advisable to enclose a variable in double quotes when that variable is being referenced. However, $x does not seem to be referenced here in your question.

y=$x does not by itself affect how whitespaces will be handled. It is only when $y is actually used that quoting matters. For example:

$ x=" a    b "
$ y=$x
$ echo $y
a b
$ echo "$y"
 a    b
n.r.
  • 1,900
  • 15
  • 20
8

From section 2.9.1 of the POSIX shell syntax specification:

Each variable assignment shall be expanded for tilde expansion, parameter expansion, command substitution, arithmetic expansion, and quote removal prior to assigning the value.

String-splitting and globbing (the steps which double quotes suppress) are not in this list, and the others aren't relevant during variable expansion (tilde expansion, for example, requires a tilde in the source code being parsed, not in the contents of a variable).

Thus, the quotes are superfluous in all simple assignments (not speaking here to those implemented with arguments to declare, export or similar commands) except those where (1) the behavior of single-quoted, not double-quoted, strings are desired; or (2) whitespace or other content in the value would be otherwise parsed as syntactic rather than literal.


(Note that the decision on how to parse a command -- thus, whether it is an assignment, a simple command, a compound command, or something else -- takes place before parameter expansions; thus, var=$1 is determined to be an assignment before the value of $1 is ever considered! Were this untrue, such that data could silently become syntax, it would be far more difficult -- if not impossible -- to write secure code handling untrusted data in bash).

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
6

There are no (good) reasons to double quote the RHS of a variable assignment when used as a statement on its own.

The RHS of an assignment statement is not subject to word splitting (or brace expansion), etc. so cannot need quotes to assign correctly. All other expansions (as far as I'm aware) do occur on the RHS but also occur in double quotes so the quoting serves no purpose.

That being said there are reasons not to quote the RHS. Namely how to address error "bash: !d': event not found" in Bash command substitution (specifically see my answer and rici's answer).

Community
  • 1
  • 1
Etan Reisner
  • 77,877
  • 8
  • 106
  • 148
2

Here are some other examples: ( having two files in the current directory t.sh and file)

a='$(ls)'        # no command substitution
b="$(ls)"        # command substitution, no word splitting
c='*'            # no filename expansion
d="*"            # no filename expansion
e=*              # no filename expansion
f=$a             # no expansions or splittings
g="$a"           # no expansions or splittings
h=$d             # no expansions or splittings

echo ---'$a'---
echo $a          # no command substitution
echo ---'$b'---
echo $b          # word splitting
echo ---'"$b"'---
echo "$b"        # no word splitting
echo ---'$c'---
echo $c          # filename expansion, word splitting
echo ---'"$c"'---
echo "$c"        # no filename expansion, no word splitting
echo ---'$d'---
echo $d          # filename expansion, word splitting
echo ---'"$d"'---
echo "$d"        # no filename expansion, no word splitting
echo ---'"$e"'---
echo "$e"        # no filename expansion, no word splitting 
echo ---'$e'---
echo $e          # filename expansion, word splitting
echo ---'"$f"'---
echo "$f"        # no filename expansion, no word splitting 
echo ---'"$g"'---
echo "$g"        # no filename expansion, no word splitting
echo ---'$h'---
echo $h          # filename expansion, word splitting
echo ---'"$h"'---
echo "$h"        # no filename expansion, no word splitting

Output:

---$a---
$(ls)
---$b---
file t.sh
---"$b"---
file
t.sh
---$c---
file t.sh
---"$c"---
*
---$d---
file t.sh
---"$d"---
*
---"$e"---
*
---$e---
file t.sh
---"$f"---
$(ls)
---"$g"---
$(ls)
---$h---
file t.sh
---"$h"---
*

One interesting thing to notice is that command substitution occurs in variable assignments if they are in double quotes, and if the RHS is given explicitly as "$(ls)" and not implicitly as "$a"..

Håkon Hægland
  • 39,012
  • 21
  • 81
  • 174
  • 1
    These examples don't vary whether the quotes are present **on the assignment**, which is the case the OP is asking about. – Charles Duffy May 25 '18 at 11:46
  • Which is to say, the question here is whether `a="$(ls)"` and `a=$(ls)` are different, not whether `echo "$a"` and `echo $a` are different. – Charles Duffy May 25 '18 at 11:56
1

Advanced Bash-Scripting Guide: Chapter 5: Quoting

When referencing a variable, it is generally advisable to enclose its name in double quotes. This prevents reinterpretation of all special characters within the quoted string. Use double quotes to prevent word splitting. An argument enclosed in double quotes presents itself as a single word, even if it contains whitespace separators.

dogbane
  • 266,786
  • 75
  • 396
  • 414
  • 3
    This is good advice in general, but in the specific case the OP mentions, quoting serves no purpose. – user000001 Dec 30 '14 at 06:43
  • Indeed, this is generally good advice (and that's almost surprising coming from the ABS as it has a tendency to make less-than-good suggestions and ignore good practice) but isn't relevant to the question being asked. – Etan Reisner May 22 '16 at 13:23
  • What guide would you recommend? – Jacob Lee May 01 '17 at 19:45
  • 1
    @JacobLee The [Bash Hackers Wiki tutorials listing](http://wiki.bash-hackers.org/scripting/tutoriallist) currently gives the highest scores to [Greg's Bash wiki's tutorial](http://mywiki.wooledge.org/BashGuide) and [Steve Parker's shell scripting guide](http://steve-parker.org/sh/intro.shtml). The ABS is somewhere in the middle with "use with caution". – tripleee May 25 '18 at 05:21
  • @dogbane, would you be opposed to an edit that switches to a different reference source? – Charles Duffy May 25 '18 at 11:47