Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

I have a bash shell function that takes an argument and perform something on it if needed.

do_somthing() {
  if [need to do something on $1]
  then
    do it
    return 0
  else
    return 1
  fi
}

I want to call this method with several arguments and check if at least one of them succeeded.

I tried something like:

if [ do_something "arg1" ||
     do_something "arg2" ||
     do_something "arg3" ]
then
  echo "OK"
else
  echo "NOT OK"
fi

What will be the correct syntax for that?
EDIT
Also - I want to make sure that even if the first condition is true all other conditions will still be evaluated.

Thanks,

share|improve this question
    
I've updated my answer. –  tectux May 11 '13 at 12:28
    
Thanks, can you please provide an example? –  Itay May 11 '13 at 12:35
    
I've added a code example to my answer. –  tectux May 11 '13 at 12:35
    
@Itay Answer updated. –  Eric Carvalho May 11 '13 at 12:37
add comment

3 Answers 3

up vote 1 down vote accepted

Run the commands first, then check if at least one of them succeeded.

#!/bin/bash

success=0
do_something arg1 && success=1
do_something arg2 && success=1
do_something arg3 && success=1

if ((success)); then
    printf 'Success! At least one of the three commands succeeded\n'
fi
share|improve this answer
    
This is confusing, I'll be glad if you could provide some explanation on how conditional statements work in bash..., do_something returns 0 upon success, but then we update success to 1..., if ((success)) evaluates to something different than if success. I am confused :) –  Itay May 13 '13 at 16:14
    
@Itay ((...)) is an arithmetic command. If the result inside, is non-zero, it returns true (0). If the result inside is 0, it returns false (1). "success" is treated as a variable which it expects to contain a number. See mywiki.wooledge.org/ArithmeticExpression –  geirha May 13 '13 at 17:37
    
Thanks, I guess that the part that confused me is that 0 is true and 1 is false usually it is the opposite :) –  Itay May 13 '13 at 18:01
1  
@Itay Yes, it may be confusing at first. Bash differs from general purpose languages in that it is "command based"; it doesn't call functions, it doesn't have classes and methods, it runs commands, and tests commands' exit statuses. And it is much easier to run commands in bash than languages like C, python, java, perl, etc.. Commands exit with 0 to signal success, and 1-255 for various types of failures. (A command can generally only succeed in one way, but fail for various different reasons) –  geirha May 13 '13 at 18:34
add comment

Use backslashes.

if [ $(do_something "arg1") ] || \
   [ $(do_something "arg2") ] || \
   [ $(do_something "arg3") ]
then
  echo "OK"
else
  echo "NOT OK"
fi

EDIT

Also - I want to make sure that even if the first condition is true all other conditions will still be evaluated.

That's not possible in only one if statement. Instead you can use a for loop that iterates over the arguments and evaluates them separately. Something like:

do_something() {
  for x in "$@"
  do
    if [need to do something on $x]
    then
      do it
    else
      echo "no action required on $x"
    fi
  done
}
share|improve this answer
    
thanks, tried it - I get an error [: do_something: unary operator expected –  Itay May 11 '13 at 11:56
    
Did you put each evaluation between its own brackets? So [ expr1 ] || [ expr2 ] instead of [ expr1 || expr2 ]. –  tectux May 11 '13 at 11:59
    
yes, I did :(... –  Itay May 11 '13 at 12:01
    
My guess is that do_something "arg1" is interpreted as two arguments whereas expression should be unary. Any way of making do_something "arg1" be evaluated as one argument? –  Itay May 11 '13 at 12:10
1  
You're right. This works too: if [ $(do_something "arg1") ]. –  tectux May 11 '13 at 12:13
show 2 more comments

The correct syntax is:

if  do_something "arg1" || \
    do_something "arg2" || \
    do_something "arg3"
then
  echo "OK"
else
  echo "NOT OK"
fi

\ is used to tell the shell a command continues in the next line.

EDIT: I think this should do what you want:

#!/bin/bash

do_something() {
  if [need to do something on $1]
  then
    do it
    echo "OK"
  else
    echo "NOT OK"
  fi
}

do_something "arg1"
do_something "arg2"
do_something "arg3"
share|improve this answer
    
Thanks, results with an error: [: too many arguments –  Itay May 11 '13 at 11:59
    
@Itay Answer updated. –  Eric Carvalho May 11 '13 at 12:13
    
Updating the question - this is not yet the final answer :( –  Itay May 11 '13 at 12:16
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.