سؤال

As the title describes, what's the proper way to do an or-assignment (eg a= b || c) in shell scripting, specifically csh vs bash? I cannot test this, so perhaps the example above works.

I thought this was pretty common in scripting languages, but for those that don't quite understand, the variable a will retain the value of b if truthy, otherwise the value of c. In the example b and c are expressions.

The usecase is typically to set to a to some kind of value if supplied, otherwise to use a default value (eg a= $1 || "Foo").


I'm not sure what the reason is for the close votes as this question is not:

  • broad
  • vague
  • incomplete

Please comment if you require some further explanation and need some amendment.

هل كانت مفيدة؟

المحلول

For bash you want

a=${b:-$c}

http://www.gnu.org/software/bash/manual/bashref.html#Shell-Parameter-Expansion

${parameter:-word}

If parameter is unset or null, the expansion of word is substituted. Otherwise, the value of parameter is substituted.

نصائح أخرى

I believe glenn jackman's got it, but I want to elaborate a little more than will fit in a comment.

Shell scripts aren't oriented around expressions. They're oriented around commands and words. Shell variables are strings by default (in the original Bourne shell, there was no way to create any other kind of variable). The RHS of an assignment isn't an "expression" the way you're thinking of it, and your b and c aren't "expressions" either, even if you wish they were.

The basic assignment syntax is

var=string

The right hand side is just a string. The shell offers a few kinds of expansions that can be used to build strings, which make it possible to do stuff like

var1=string
var2=$var1
var3="This is a ${var1}"
var4=$(ls | wc -l)
var5=$(($var4 + 1))

The value that is assigned to each variable is the string on the RHS with some expansions (marked by $) performed in it.

The last example, with $((...)), is the only one that really contains something that can be called an "expression". The double-parenthesized expansion works on arithmetic expressions, so this would be the thing to use if your b and c are numeric.

So you should stop thinking of your desired result in terms of an expression being evaluated with the two child expressions b and c as inputs, because the concepts just don't generalize that way in the shell language.

If b is a variable and you want to expand it with a default value to be used when the variable is unset, then use ${b-c}. If you also want the default value to be used when the variable is set but empty, then use ${b:-c}. The c in these examples is a string, and like all other strings in the shell it can be built with expansions:

i=3
var=""
echo ${var:-$(cat somefile)} # since var is empty, substitute file contents
echo ${var:-$(($i * $i))} # since var is empty, do some math instead

Now if your b is not a variable like $var, you'll probably find that none of the above applies! Because The ${...:-...} syntax is for variable expansion. You really will have to specify what b is, and you can't say "expression" because in the shell there's no such thing.

I'm guessing you mean this (in bash):

a=1
b=2
echo $(( $a | $b ))

Which results in 3: 1 | 2

The operators are |, ^, &, >>, and <<

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top