1

Are the quotes in the below example necessary or superfluous. And why?

#!/bin/bash

arg1="$1"
arg2="$2"

How do you explain the fact when $1 is 123 echo abc, the first assignment is not interpreted as:

arg1=123 echo abc

which is a normal command (echo) call with argument abc and an environment variable (arg) passed to the execution.

codeforester
  • 39,467
  • 16
  • 112
  • 140
Gabriel Petrovay
  • 20,476
  • 22
  • 97
  • 168
  • 1
    Even if the syntax *didn't* specify that assignments don't go through string-splitting, that doesn't mean you can get from `arg=$1` to `arg=123 echo abc` *with the arg=123 interpreted as a transient environment variable assignment*. Parsing for syntax (and such environment variables' assignments are indeed syntax) happens **before** variable expansion; this is also why you can't set `var='if'` and then run `$var foo; then bar; fi`, because keywords (like assignments!) are only recognized prior to the point when parameter expansion takes place. – Charles Duffy May 24 '18 at 21:15
  • 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:18

1 Answers1

3

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.

Thus, the quotes are superfluous -- not just for assignments where the right-and side refers to a positional parameter, but for all assignments barring 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
    While superfluous in this context, quoting is so important in all others that I feel assignments to should be quoted to reinforce the habit. – bishop May 24 '18 at 21:22
  • 3
    As a matter of best practice, I agree. – Charles Duffy May 24 '18 at 21:24
  • How should I properly read this? `$1` is expanded (prior to assignment), this generates white spaces and then bash should work as I describe: execute `echo`. Is there a difference between how `$1` and a normal variable `$var` are processed? Can we also say that quotes are always superfluous for all single-variable-expansion assignments? – Gabriel Petrovay May 24 '18 at 21:32
  • 3
    @GabrielPetrovay, yes, quotes are superfluous for assignments *in general*, except where there would be syntactic whitespace causing them to otherwise be parsed as an entirely different kind of command. They're just as superfluous for `arg3=${foo}${bar}`, for example. – Charles Duffy May 24 '18 at 21:33
  • Yours is better than any of the answers on the duplicate, could you please repost it there (and perhaps delete it from here)? – tripleee May 25 '18 at 05:22
  • 1
    @tripleee, ...done; can't delete from here due to accepted status, but flagged this copy community-wiki. – Charles Duffy May 25 '18 at 11:43