4

How can I write an 'if then' statement to switch between these to variables as in the following?

if(switch){
  server_var_shortname=$server_shared_shortname
  server_var=$server_shared
  server_var_bare=$server_shared_bare
} else {
  server_var_shortname=$server_vps_shortname
  server_var=$server_vps
  server_var_bare=$server_vps_bare
}

I'm not familiar with Bash syntax and basically just need an 'if/else' statement on a Boolean. Also, can I use true / false values as such? Also how do I do the 'else' statement?

$switch=true;
if $switch
then
  server_var_shortname=$server_shared_shortname
  server_var=$server_shared
  server_var_bare=$server_shared_bare
fi
1
  • The duplicate I chose covers the 'boolean' aspects of this question, without going over the more elementary but also important mechanics of if, then, elif, else, fi in Bash and other POSIX-like shells. The notation in the question is more C-like — the C shell supports that notation more directly, but you probably shouldn't use the C shell, especially not for serious scripting work (search 'csh programming considered harmful' for explanations of why; sea shells should be left on the sea shore). Commented Apr 1, 2017 at 17:40

5 Answers 5

8

First, shells (including Bash) don't have Booleans; they don't even have integers (although they can sort of fake it). Mostly, they have strings.

Bash also has arrays... of strings. There are a number of ways of faking Booleans; my favorite is to use the strings "true" and "false". These also happen to be the names of commands that always succeed and fail respectively, which comes in handy, because the if statement actually takes a command, and runs the then clause if it succeeds and the else clause if it fails. Thus, you can "run" the Boolean, and it'll succeed if set to "true" and fail if set to "false". Like this:

switch=true  # This doesn't have quotes around it, but it's a string anyway.
# ...
if $switch; then
    server_var_shortname=$server_shared_shortname
    server_var=$server_shared
    server_var_bare=$server_shared_bare
else
    server_var_shortname=$server_vps_shortname
    server_var=$server_vps
    server_var_bare=$server_vps_bare
fi

Note that the more usual format you'll see for if has square-brackets, like if [ something ]; then. In this case, [ is actually a command (not some funny sort of grouping operator) that evaluates its argument as an expression; thus [ "some string" = "some other string" ] is a command that will fail because the strings aren't equal. You could use if [ "$switch" = true ]; then, but I prefer to cheat and use the fake Boolean directly.

Caveat: if you do use the cheat I'm suggesting, make sure your "Boolean" variable is set to either "true" or "false" -- not unset, not set to something else. If it's set to anything else, I take no responsibility for the results.

Some other syntax notes:

  • Use $ on variables when fetching their values, not when assigning to them. You have $switch=true; up there, which will get you an error.
  • Also, you have a semicolon at the end of that line. This is unnecessary; semicolons are used to separate multiple commands on the same line (and a few other places), but they aren't needed to end the last (/only) command on a line.
  • The [ command (which is also known as test) has a kind of weird syntax. Mostly because it's a command, so it goes through the usual command parsing, so e.g. [ 5 > 19 ] is parsed as [ 5 ] with output sent to a file named "19" (and is then true, because "5" is nonblank). [ 5 ">" 19 ] is better, but still evaluates to true because > does string (alphabetical) comparisons, and "5" is alphabetically after "19". [ 5 -gt 19 ] does the expected thing.

    There's also [[ ]] (similar, but cleaner syntax and not available in all shells) and (( )) (for math, not strings; also not in all shells). See Bash FAQ #31.

  • Putting commands in variables is generally a bad idea. See Bash FAQ #50.

  • shellcheck.net is your friend.
1

Here is a good guide for If else. But I want to show a different approach (which you will find also in the link on page 3).

Your coding looks like JavaScript, so I think with Switch you could also mean the case command instead of if. Switch in JavaScript is similar to case within a shell, but there isn't any method to check for Booleans. You can check string values for like true and false, and you can check for numbers.

Example...

#!/bin/bash
case "$Variable" in
false|0|"")
    echo "Boolean is set to false."
;;
*)
    echo "Boolean is set to true."
;;
esac

Addition

Keep in mind, there are many programs and tools that uses Boolean values in different forms.

Two examples...
SQL in general uses numbers as Boolean.
JavaScript uses true and false values.

Meaning: Your Bash script has to know the format of Booleans, before processing them!

0

Bash doesn't have any concept of Boolean - there are no true / false values. The construct

[ $switch ]

will be true except when switch variable is not set or is set to an empty string.

[ ]    && echo yes                      # Nothing is echoed
[ "" ] && echo yes                      # Nothing is echoed
unset switch && [ $switch ] && echo yes # Nothing is echoed
switch=1 && [ $switch ] && echo yes     # 'yes' is echoed
switch=0 && [ $switch ] && echo yes     # 'yes' is echoed - the shell makes no distinction of contents - it is true as long it is not empty

See also:

1
0

You need something like this:

if
  CONDITION_SEE_BELOW
then
  server_var_shortname=$server_shared_shortname
  server_var=$server_shared
  server_var_bare=$server_shared_bare
else
  server_var_shortname=$server_vps_shortname
  server_var=$server_vps
  server_var_bare=$server_vps_bare
fi

In Bash (and other shells), the CONDITION_SEE_BELOW part has to be a command. A command returns a numerical value, and by convention 0 means "true" and any non-zero value means "false". The then clause will execute if the command returns 0, or the else clause in all other cases. The return value is not the text output by the command. In shells, you can access it with the special variable expansion $? right after executing a command.

You can test that with commands true and false, which do one thing: generate a zero (true) and non-zero (false) return value. Try this at the command line:

true ; echo "true returns $?"
false ; echo "false returns $?"

You can use any command you want in a condition. There are two commands in particular that have been created with the idea of defining conditions: the classic test command [ ] (the actual command only being the opening bracket, which is also available as the test command), and the double-bracketed, Bash-specific [[ ]] (which is not technically a command, but rather special shell syntax).

For instance, say your switch variable contains either nothing (null string), or something (string with at least one character), and assume in your case you mean a null string to be "false" and any other string to be "true". Then you could use as a condition:

[ "$switch" ]

If you are OK with a string containing only spaces and tabs to be considered empty (which will happen as a result of standard shell expansion and word splitting of arguments to a command), then you may remove the double quotes.

The double-bracket test command is mostly similar, but has some nice things about it, including double-quoting not being needed most of the time, supporting Boolean logic with && and || inside the expression, and having regular expression matching as a feature. It is, however a Bashism.

You can use this as a reference to various tests that can be performed with both test commands:

6.4 Bash Conditional Expressions

If at all interested in shell programming, be sure to find out about the various tests you can use, as you are likely to be using many of them frequently.

0

As addition to Gordon's excellent answer, in Bash you can also use the double-parentheses construct. It works for integers, and it is the closest form to other languages. Demo:

for i in {-2..2}; do
    printf "for %s " "$i"

    if (( i ))   # You can omit the `$`
    then
        echo is nonzero
    else
        echo is zero
    fi

done

Output:

for -2 is nonzero
for -1 is nonzero
for 0 is zero
for 1 is nonzero
for 2 is nonzero

You can use any arithmetic operations inside, e.g.:

for i in {1..6}; do
    printf "for %s " "$i"

    if (( i % 2 )) #modulo
    then
        echo odd
    else
        echo even
    fi
done

Output

for 1 odd
for 2 even
for 3 odd
for 4 even
for 5 odd
for 6 even