1

Simple Bash +1 please

Hey there. I know I'm missing something simple in this script. But what is it? an exit? fi? When I use Name -online i get the echo "Bool Changed offline2" from the very last section. Online code shouldnt clash with Offline. Help, I've been at this for hours.

if [ "$1" == "-online" ]; then
        if [ "$Check" == "com.company.package1" ]; then
            plutil -key settingsOfflineMode -value 0 -type bool /the/dir/ect/ory/com.company.package1 &> /dev/null
            echo "Bool Changed online1"
            exit
        fi
    else
        if [ "$Check" == "com.company.package2" ]; then
            plutil -key settingsOfflineMode -value 0 -type bool /the/dir/ect/ory/com.company.package2 &> /dev/null  ////EDITED TO com.company.package2
            echo "Bool Changed online2"
            exit        
        fi
    fi


if [ "$1" == "-offline" ]; then
        if [ "$Check" == "com.company.package1" ]; then
            plutil -key settingsOfflineMode -value 0 -type bool /the/dir/ect/ory/com.company.package1 &> /dev/null
            echo "Bool Changed offline1"
            exit
        fi
    else
        if [ "$Check" == "com.company.package2" ]; then
            plutil -key settingsOfflineMode -value 0 -type bool /the/dir/ect/ory/com.company.package2 &> /dev/null  //EDITED TO com.company.package2
            echo "Bool Changed offline2"
            exit        
        fi
    fi
CokePokes
  • 941
  • 3
  • 12
  • 25
  • Your code looks ok, although as posted, it lacks a shebang line. Are you sure it's executed by Bash? Try `bash -x Name -online`, maybe without the `-x` at first. – tripleee Jan 18 '12 at 18:10
  • The `plutil` command seems to be identical in all branches, is that intentional? – tripleee Jan 18 '12 at 18:15
  • Once the indentation is adjusted the problem could be clearer. – MRAB Jan 18 '12 at 18:06
  • According to `man test`, you should use `=`, not `==`. Not sure if that's the problem, though. – svick Jan 18 '12 at 18:18
  • This is executed on iPhone. the -online works fine without the -offline, so when the offline part is added the the online command doesnt work anymore. I only get Bool Changed offline2 – CokePokes Jan 18 '12 at 18:26
  • @svick: In Bash `==` is perfectly valid, however `[[` is preferred over `[`. See [BashFAQ/031](http://mywiki.wooledge.org/BashFAQ/031) and my answers [here](http://stackoverflow.com/questions/3869072/test-for-non-zero-length-string-in-bash-n-var-or-var/3870055#3870055) and [here](http://stackoverflow.com/questions/2188199/bash-double-or-single-bracket-parentheses-curly-braces/2188369#2188369). – Dennis Williamson Jan 18 '12 at 20:55

6 Answers6

4

Assuming that $Check is set to "com.company.package2" (which, unfortunately you don't show), this is what your script is doing:

  • The first if is true because the command argument is "-online".
  • The second if is false ("package2" != "package1")
  • The first else is skipped since the first if was true
  • The "-offline" if is false, so its else path is taken
  • The final if is true ("package2" != "package2") so the message is echoed

else if is not the same as elif

Because you close the inner if statements with fi, the else is evaluated for the outer if statements.

You probably want:

#!/bin/bash

Check=com.company.package2

if [[ $1 == "-online" ]]; then
        if [[ $Check == "com.company.package1" ]]; then
            plutil -key settingsOfflineMode -value 0 -type bool /the/dir/ect/ory/com.company.package1 &> /dev/null
            echo "Bool Changed online1"
            exit
        elif [[ $Check == "com.company.package2" ]]; then
            plutil -key settingsOfflineMode -value 0 -type bool /the/dir/ect/ory/com.company.package2 &> /dev/null  ////EDITED TO com.company.package2
            echo "Bool Changed online2"
            exit
        fi
elif [[ $1 == "-offline" ]]; then
        if [[ $Check == "com.company.package1" ]]; then
            plutil -key settingsOfflineMode -value 0 -type bool /the/dir/ect/ory/com.company.package1 &> /dev/null
            echo "Bool Changed offline1"
            exit
        elif [[ $Check == "com.company.package2" ]]; then
            plutil -key settingsOfflineMode -value 0 -type bool /the/dir/ect/ory/com.company.package2 &> /dev/null  //EDITED TO com.company.package2
            echo "Bool Changed offline2"
            exit
        fi
fi
Dennis Williamson
  • 346,391
  • 90
  • 374
  • 439
0

the elses shall be in the inner if, right? i think that's the problem! use elif instead

if [ "$Check" == "com.company.package1" ]; then
    ...
elif [ "$Check" == "com.company.package2" ]; then
    ...
fi
v01pe
  • 1,096
  • 2
  • 11
  • 19
  • `elif` is just a shorthand; `else if` is legal as well. – tripleee Jan 18 '12 at 18:12
  • This did not work. Still getting just the Bool Changed offline2 echo. Offline shouldn't even be executed when running the online command. I have to be missing an if, fi or exit. But WHERE? – CokePokes Jan 18 '12 at 18:36
  • @tripleee: `elif` (which does not need its own `fi`) is _not_ just shorthand for `else if` (which _does_ need its own `fi`). – Dennis Williamson Jan 18 '12 at 21:43
0

replace your else by elif:

if [ "$1" == "-online" ]; then
    if [ "$Check" == "com.company.package1" ]; then
        echo "Bool Changed online1"
        exit
    elif [ "$Check" == "com.company.package2" ]; then
        echo "Bool Changed online2"
        exit
    fi
fi

if [ "$1" == "-offline" ]; then
    if [ "$Check" == "com.company.package1" ]; then
        echo "Bool Changed offline1"
        exit
    elif [ "$Check" == "com.company.package2" ]; then
        echo "Bool Changed offline2"
        exit
    fi
fi

echo "Combination [Check=$Check / param1=$1] did not match any case"

EDIT: oops I have just understood @v01pe means the same :-/

oHo
  • 51,447
  • 27
  • 165
  • 200
0

It's seems that $Check is equal to com.company.package2.

You're branching to the first if statement because your argument is "-online" then $Check does not equal to com.company.package1 so you quit this if without doing nothing...

Comes the second if statement that checks for -offline which is not a true statement in your case, then you branch in the else ...

Finally $Check is equal com.company.package2 and you print your echo command ...

Debugger
  • 9,130
  • 17
  • 45
  • 53
0

I've cleaned up your code:

  • I use = instead of == for string equals. Newer versions of Bash will take either one. However, earlier version would only take == in [[ and ]] tests, and sometimes simply didn't do what you expect.
  • Combine your if statements with either [ ... ] && [ ... ] syntax or [ ... -a ... ] syntax. That will simplify your logic. [[ ... && ... ]].
  • Use elif instead of putting an if clause inside the else clause. Again, it simplifies your syntax.
  • Removed exits. The entire logic structure now only executes one of the four conditions. No need for the exits in this content.
  • Where is $Check set? Is it a variable set outside your program? If so, make sure it's been exported so it is defined in sub-shells and shell scripts.

After I made the changes, the script seemed to work. I had to set $Check before running the script and I had to nop out the plutil command since I don't have that on my system, but the logic works.

The big thing you can do is to set set -xv when you run your shell script. This turns on debugging. The -x prints out the command line after expanding and shows you what was set. The -v shows you the command line being executed as written.

For example:

$ set -v
$ ls f*
ls f*
foo.txt foobar.txt
$ set -x
ls f*
ls foo.txt foobar.txt
foo.txt foobar.txt

To turn off debugging, simply do a set +xv. In fact, you can do set -xv and set +xv in the sections of a long shell script where you're having problems. That way, you're not overwhelmed with debugging information.

Here's your program:

#! /bin/bash

#set -xv

if [[ "$1" == "-online" ]]; then
    if [[ "$Check" == "com.company.package1" ]]; then
        plutil -key settingsOfflineMode -value 0 -type bool /the/dir/ect/ory/com.company.package1 &> /dev/null
        echo "Bool Changed online1"
    elif [[ "$Check" == "com.company.package2" ]]; then
        plutil -key settingsOfflineMode -value 0 -type bool /the/dir/ect/ory/com.company.package2 &> /dev/null  ////EDITED TO com.company.package2
        echo "Bool Changed online2"
    fi
elif [[ "$1" == "-offline" ]]; then
    if [[ "$Check" == "com.company.package1" ]]; then
        plutil -key settingsOfflineMode -value 0 -type bool /the/dir/ect/ory/com.company.package1 &> /dev/null
        echo "Bool Changed offline1"
    elif [[ "$Check" == "com.company.package2" ]]; then
        plutil -key settingsOfflineMode -value 0 -type bool /the/dir/ect/ory/com.company.package2 &> /dev/null  //EDITED TO com.company.package2
        echo "Bool Changed offline2"
    fi
fi
David W.
  • 105,218
  • 39
  • 216
  • 337
  • In your first bullet point, you refer to double square brackets, yet in the rest of your answer you use single ones (as does the OP). All versions of Bash since at least 2.05b accept either `=` or `==` inside `[[ ]]` (also ksh93 and zsh). Some Bourne-derived shells (e.g. the original `sh` and Dash) do not support double square brackets and thus do not support double equals. In Bash, the preferred conjunction would be `[[ ... && ... ]]` rather than putting the ampersands outside or using `-a`. Of course, those that need or insist on portability would prefer not to use Bash-specific features. – Dennis Williamson Jan 19 '12 at 14:47
  • @DennisWilliamson - I work in a whole bunch of different Bourne type shells, so I tend to program to the lowest common denominator. In Kornshell, the [[ $foo == $bar ]] is not necessarily an equality, but a pattern match. Out of habit, I tend to use single brackets and a single equals because I know it works with both. However, I'll update my answer to use `[[ ]]` since that's what is really preferred. – David W. Jan 19 '12 at 19:11
  • In Bash, it's also a pattern match. The following applies to both Bash and ksh: If the item on the right is an unquoted string or unquoted variable and contains globbing characters, then the string on the left is compared using the usual globbing rules. If the right side item is quoted, then the globbing characters are taken literally instead. The use of `==` or `=` makes no difference. – Dennis Williamson Jan 19 '12 at 20:04
-1

Could it be the ';' right after your if clauses?

if [ "$1" == "-online" ]**;** then