Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Can I safely omit quotes on the right side of a local assignment?

function foo {
    local myvar=${bar}
    stuff()
}

I'm mainly interested in bash, but any info on corner cases in other shells are welcome.

share|improve this question
    
I think it makes no difference if it is on one line like you have it in your function. Assignments do not need quoting. See mpi-sb.mpg.de/departments/rg1/teaching/unixffb-ss98/… –  Jiri Xichtkniha Oct 25 '13 at 13:48

2 Answers 2

up vote 9 down vote accepted

Quotes are needed in export foo="$var" or local foo="$var" (or typeset, declare and other variable declaring commands) in:

  • dash
  • yash
  • zsh in bash or sh emulation

As otherwise they would be subject to word splitting or filename generation like in any argument to any other command.

And are not needed in bash or ksh (where the command is somehow parsed like some sort of assignment) nor zsh (where word splitting and filename generation is not done implicitly upon variable expansion).

They are needed in every shell though in things like:

a="b=some value"
export "$a"

They are not needed in any shell when written:

foo=$var export foo

(that syntax being also compatible with the Bourne shell).

(note that var=value local var shouldn't be used as the behaviour varies across shells).

Also beware of this special case with bash:

$ bash -c 'IFS=; export a="$*"; echo "$a"' bash a b
ab
$ bash -c 'IFS=; export a=$*; echo "$a"' bash a b
a b

My advise would be to always quote.

share|improve this answer
1  
Note that in zsh quotes are needed for local foo="$(cmd)" because wordsplitting (but not filename generation) is performed for unquoted command substitutions (but not for unquoted parameter expansions), unless KSH_TYPESET is enabled, in which case quotes aren't needed. Make sense? No? Then always quote everything unless you know exactly what you're doing. –  Matt Oct 25 '13 at 17:39

I generally quote any usage of variables where there might be characters such as white spaces. Otherwise you'll run into problems like this:

#!/bin/bash

bar="hi bye"

function foo {
  local myvar=${bar}
  printf "%s\n" $myvar
  printf "%s\n" "$myvar"
}

foo

The usage of the variable in an assignment doesn't appear to need the quotes, but when you go to use it such as in the printf you'll need it quoted there:

  printf "%s\n" "$myvar"

NOTE: Remember that the variable $IFS is what governs what the separator characters are.

IFS    The  Internal  Field  Separator that is used for word splitting after 
       expansion and to split lines into words with the read builtin command. 
       The default value is ``<space><tab><newline>''.

Example

With debugging enabled in Bash we can see what's happening behind the scenes.

$ bash -x cmd.bash 
+ bar='hi bye'
+ foo
+ local 'myvar=hi bye'
+ printf '%s\n' hi bye
hi
bye
+ printf '%s\n' 'hi bye'
hi bye

In the above we can see that the variable, $bar was handed off fine to $myvar but then when we went to use $myvar we had to be cognoscente of the contents of $myvar when we went to use it.

share|improve this answer
    
word splitting is not the only problem with unquoted variables, you have to consider filename generation (aka globbing) as well (though that (both) doesn't apply in variable assignments and for bash and ksh in local/typeset... special builtins). –  Stéphane Chazelas Oct 25 '13 at 13:58

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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