Aleksandr Levchuk
Aleksandr Levchuk

Reputation: 3881

Bash test if an argument exists

I want to test if an augment (e.g. -h) was passed into my bash script or not.

In a Ruby script that would be:

#!/usr/bin/env ruby
puts "Has -h" if ARGV.include? "-h"

How to best do that in Bash?

Upvotes: 12

Views: 14030

Answers (4)

JBSnorro
JBSnorro

Reputation: 6706

I'm trying to solve this in a straightforward but correct manner, and am just sharing what works for me.

The dedicated function below solves it, which you can use like so:

if [ "$(has_arg "-h" "$@")" = true ]; then
    # TODO: code if "-h" in arguments
else
    # TODO: code if "-h" not in arguments
fi

This function checks whether the first argument is in all other arguments:

function has_arg() {
    ARG="$1"
    shift
    while [[ "$#" -gt 0 ]]; do
        if [ "$ARG" = "$1" ]; then
            echo true
            return
        else
            shift
        fi
    done
    echo false
}

Upvotes: 0

kitingChris
kitingChris

Reputation: 678

The simplest solution would be:

if [[ " $@ " =~ " -h " ]]; then
   echo "Has -h"
fi

Upvotes: 10

Jonathan Leffler
Jonathan Leffler

Reputation: 753505

It is modestly complex. The quickest way is also unreliable:

case "$*" in
(*-h*) echo "Has -h";;
esac

Unfortunately that will also spot "command this-here" as having "-h".

Normally you'd use getopts to parse for arguments that you expect:

while getopts habcf: opt
do
    case "$opt" in
    (h) echo "Has -h";;
    ([abc])
        echo "Got -$opt";;
    (f) echo "File: $OPTARG";;
    esac
done

shift (($OPTIND - 1))
# General (non-option) arguments are now in "$@"

Etc.

Upvotes: 2

Aleksandr Levchuk
Aleksandr Levchuk

Reputation: 3881

#!/bin/bash
while getopts h x; do
  echo "has -h";
done; OPTIND=0

As Jonathan Leffler pointed out OPTIND=0 will reset the getopts list. That's in case the test needs to be done more than once.

Upvotes: 3

Related Questions