5

This question already has an answer here:

This question is about assigning the entire contents of one variable to another variable.

Variable is not being used (sent to echo, etc.)

No parameter expansion is being done during the assignment.

My question also pertains only to POSIX shell (no arrays being used here).

error="You have an error in your input"

newVar="$error"
# vs.
newVar=$error
#         ↑
#         └─This assignment is the question. It doesn't seem that quotes are
#           needed here in order to assign the entire contents of $error to
#           a new variable.

#                 ┌─(But quotes are required when they're used.)
#                 ↓
printf "%s\n" "$error"
# => You have an error in your input
printf "%s\n" "$newVar"
# => You have an error in your input

Are there any gotchas I'm missing in just writing newVar=$error?

Update:

Regardless of what's in $error, I want to know will that same data carry over into $newVar without throwing any errors or mangling the data.

$ error="Test * ${1} \n [!a] [[:punct:]] ./test \t \n \\"
$ newVar=$error
#       ↑
#       └─Does this step ever fail or cause the two variables to differ?
$ echo "$error"
Test *  \n [!a] [[:punct:]] ./test \t \n \
$ echo "$newVar"
Test *  \n [!a] [[:punct:]] ./test \t \n \

marked as duplicate by G-Man, Justin Ethier, vonbrand, chaos, cuonglm Aug 6 '15 at 2:10

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • 2
    You can refer to this. – cuonglm Aug 5 '15 at 16:39
  • tangentially, you may be misunderstanding the action of printf -- if you give it one "Argument no matter how many spaces, in quotes" then it will print the formatted values only once. If you instead give printf an unquoted variable with spaces in it, then it will repeat the format string for each. – Jeff Schaller Aug 5 '15 at 16:41
  • If you're going to play with edge cases, you should probably stick to printf "%s\n" "$var", because echo "$var" is less predictable/reliable when $var begins with dash (-) or contains backslash (\).  (And of course printf "$var" is unforgiving if $var contains percent (%) or backslash (\).) – G-Man Aug 5 '15 at 19:21
  • 2
    @EvgenyVereshchagin No, that question only touches this subject in passing. unix.stackexchange.com/questions/68694/… might be considered a duplicate. – Gilles Aug 5 '15 at 22:36
12

In Bourne-like shells (if we forget about bugs1 in some old implementations of some shells)

var=$otherVar

is fine. You're assigning to a scalar variable, so there can't be glob+splitting here, so you don't need to write it var="$otherVar" (though the quotes don't harm here).

An exception is for:

var=$*

and:

var=$@

You should only use var="$*". The behaviour of var=$@ var=$* var="$@" varies among shells when the first character of $IFS is not space.

Of course, in:

array=("$var")

You do need the quotes, as otherwise, the array elements would be assigned the result of the split+globbing of $var.

Also note that you need the quotes in:

export var="$otherVar"

with many shells (in them, here, it's a simple command, so split+glob occurs).

And in:

env var="$otherVar" cmd

Or

awk -v var="$otherVar"...

If in doubt, use the quotes.


1 Some old versions of zsh had an issue with backslash in front of wildcard characters when in sh emulation:

$ (a='\*' exec -a sh zsh-3.1.9 -c 'b=$a; printf "%s\n" "$b"')
*
$ (a='\*' exec -a sh zsh-3.1.9 -c 'b="$a"; printf "%s\n" "$b"')
\*

That was fixed a long time ago.

Not the answer you're looking for? Browse other questions tagged or ask your own question.