Yes, x=$y
and x="$y"
are guaranteed to be the same in a POSIX shell. If you or some other reader of your code are unsure where double quotes must be used (see When is double-quoting necessary?), including the double quotes may be the safer option, as to not introduce confusion.
From the POSIX specification (section 2.9.1, "Simple Commands"):
When a given simple command is required to be executed [...], the following expansions, assignments, and redirections shall all be performed from the beginning of the command text to the end:
- The words that are recognized as variable assignments or redirections according to Shell Grammar Rules are saved for processing in steps 3 and 4.
[...]
- Redirections shall be performed as described in Redirection.
- Each variable assignment shall be expanded for tilde expansion, parameter expansion, command substitution, arithmetic expansion, and quote removal prior to assigning the value.
Note that the fourth point does not include field splitting or pathname expansion ("globbing"), which are usually part of the expansions done when the word is not recognised as a variable assignment. Since these steps are removed for assignments, the quoting is not necessary.
See also section 2.6, "Word Expansions":
The order of word expansion shall be as follows:
- Tilde expansion (see Tilde Expansion), parameter expansion (see Parameter Expansion), command substitution (see Command Substitution), and arithmetic expansion (see Arithmetic Expansion) shall be performed, beginning to end. See item 5 in Token Recognition.
- Field splitting (see Field Splitting) shall be performed on the portions of the fields generated by step 1, unless
IFS
is null.
- Pathname expansion (see Pathname Expansion) shall be performed, unless
set -f
is in effect.
- Quote removal (see Quote Removal) shall always be performed last.
The following only matters if y
in x=$y
and x="$y"
is actually one of the special parameters *
or @
:
Note that since "$@"
expands to a list of strings, it is unspecified what x=$@
and x="$@"
do, while x=$*
is the same as x="$*"
. In some shells (e.g. bash
, ksh93
), using $@
like this is the same as using $*
when the first character of $IFS
is a space, while in others (e.g. busybox sh
, dash
, zsh
) it's the same as $*
and uses the first character of the set value of $IFS
.