Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I'm trying to write a script where I want to check if any of the parameters passed to a bash script match a string. The way I have it setup right now is

if [ "$3" != "-disCopperBld" -a "$4" != "-disCopperBld" -a "$5" != "-disCopperBld" -a "$6" != "-disCopperBld"]

but there might be a large number of parameters, so I was wondering if there is a better way to do this?

Thanks

EDIT: I tried this chunk of code out, and called the script with the option, -disableVenusBld, but it still prints out "Starting build". Am I doing something wrong? Thanks in advance!

while [ $# -ne 0 ]
do
    arg="$1"
    case "$arg" in
        -disableVenusBld)
            disableVenusBld=true
            ;;
        -disableCopperBld)
            disableCopperBld=true
            ;;
        -disableTest)
            disableTest=true
            ;;
        -disableUpdate)
            disableUpdate=true
            ;;
        *)
            nothing="true"
            ;;
    esac
    shift
done

if [ "$disableVenusBld" != true ]; then
    echo "Starting build"
fi
share|improve this question
    
Thanks for the replies guys, I appreciate ya'll taking time out to help me. I tried a chunk of code, but I can't seem to figure out what's going wrong. Any ideas? (I've pasted the code in an edit of my original post) –  iman453 Sep 9 '10 at 15:29
    
Hmm: it works for me. I added #! /bin/sh - to the top of what you've included there, made the script executable, then ./t.sh prints "Starting build", but ./t.sh -disableVenusBld prints nothing. –  Norman Gray Sep 9 '10 at 21:47

3 Answers 3

up vote 16 down vote accepted

It looks like you're doing option handling in a shell script. Here's the idiom for that:

#! /bin/sh -

# idiomatic parameter and option handling in sh
while test $# -gt 0
do
    case "$1" in
        --opt1) echo "option 1"
            ;;
        --opt2) echo "option 2"
            ;;
        --*) echo "bad option $1"
            ;;
        *) echo "argument $1"
            ;;
    esac
    shift
done

exit 0

(There are a couple of conventions for indenting the ;;, and some shells allow you to give the options as (--opt1), to help with brace matching, but this is the basic idea)

share|improve this answer
    
A shift statement is used when the number of arguments to a command is not known in advance, for instance when users can give as many arguments as they like. In such cases, the arguments are processed in a while loop with a test condition of $#. This condition is true as long as the number of arguments is greater than zero. The $1 variable and the shift statement process each argument. The number of arguments is reduced each time shift is executed and eventually becomes zero, upon which the while loop exits. source –  Serge Stroobandt Jan 22 at 22:47
    
Here is a similar example with additional echo $1 | sed argument value processing. –  Serge Stroobandt Jan 22 at 22:57

This worked for me. It does exactly what you asked nothing more (no option processing). Whether that's good or bad is an exercise for the poster :)

if [[ "$@" == "your string" ]]
then
    echo "YES"
else
    echo "NO"
fi

Note that the usage of $@, instead of $*, together with the fact that it is quoted, guarantees the flexibility in case of a test string with whitespeces. With $* only "your" or "string" would be matched. There would be no difference, however, if there are no whitespaces.

See this explanation about the differences in the behavior.

share|improve this answer
1  
IMHO this had to be the most correct answer, since the question requires only to check the presence of a parameter. I have edited, however, changing $* to $@, since the to-be-tested string might have spaces and added link to bash's documentation about it. –  h7r Feb 1 at 12:51
    
Did you mean to use the =~ operator? Otherwise I don't see why this should work, and indeed it doesn't work when I try the exact script. –  Seppo Enarvi Jul 14 at 8:37
disCopperBld=
for x; do
  if [ "$x" = "-disCopperBld" ]; then disCopperBld=1; break; fi
done
if [ -n "$disCopperBld" ]; then
  ...
fi

If you need to test only the parameters starting at $3, do the search in a function:

## Usage: search_trailing_parameters NEEDLE NUM "$@"
## Search NEEDLE amongst the parameters, skipping $1 through ${$NUM}.
search_trailing_parameters () {
  needle=$1
  shift $(($2 + 2))
  for x; do
    if [ "$x" = "$needle" ]; then return 0; fi
  done
  return 1
}
if search_trailing_parameters -disCopperBld 2 "$@"; then
  ...
fi

But I wonder why you're trying to do this in the first place, it's not a common need. Usually, you'd process options in order, as in Dennis's answer to your previous question.

share|improve this answer

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.