These do slightly different things. In fact, the last one echo ${x-1} doesn't in fact set x but substitutes the value 1 in the expression only if x isn't set.
x=1 on the other hand sets x unconditionally.
As for the := operator. This is from the ksh manual:
${parameter:=word}
If parameter is not set or is null then set it to word; the
value of the parameter is then substituted. Positional parameters may
not be assigned to in this way.
In Ruby, this is like ||=.
And if you look at the family of x= operators there are many more, :- being the most popular that I have run across. That one substitutes a variable to a default value if the variable hasn't been set. So you use it like:
x=${1:-10}
which in English is: If $1 is null or the empty stringunset assign 10 to x, otherwise assign to x the value of $1. In a function this has the effect of assigning a default value to a parameter. So
f() {
typeset x
x=${1-10}
...
}
is equivalent to Python:
def f(x=10):
I think David Korn will admit that the variety of operators was probably overkill, but it is now part of the POSIX standard, Section 2.6.2 so it is probably there to stay.
Even programming languages do not have more than one.
As alluded to above, there's a misconception that these are exactly the same. It is not uncommon in programming languages to have variations of the assignment statement. I mentioned ||= in Ruby. Many languages have +=, -= and so on. In Perl if you run $x += 1 that will set $x to 1 if $x hasn't been defined before (and, shame on you, if you don't have "strict" checking enabled).