33

I don't know whether it's possible, but I want to write shell scripts that act like regular executables with options. As a very simple example, consider a shell script foo.sh that is configured to be executable:

    ./foo.sh
    ./foo.sh -o

and the code foo.sh works like

    #!/bin/sh
    if  ## option -o is turned on
        ## do something
    else
        ## do something different
    endif

Is it possible and how to do that? Thanks.

5 Answers 5

36
$ cat stack.sh 
#!/bin/sh
if  [[ $1 = "-o" ]]; then
    echo "Option -o turned on"
else
    echo "You did not use option -o"
fi

$ bash stack.sh -o
Option -o turned on

$ bash stack.sh
You did not use option -o

FYI:

$1 = First positional parameter
$2 = Second positional parameter
.. = ..
$n = n th positional parameter

For more neat/flexible options, read this other thread: Using getopts to process long and short command line options

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks. Actually I know the argument trick, but that's too lame... getopt looks cool.
that option must be then only the first parameter? And if I have two options, how do you distinguish?
27

this is the way how to do it in one script:

#!/usr/bin/sh
#
# Examlple of using options in scripts
#

if [ $# -eq 0 ]
then
        echo "Missing options!"
        echo "(run $0 -h for help)"
        echo ""
        exit 0
fi

ECHO="false"

while getopts "he" OPTION; do
        case $OPTION in

                e)
                        ECHO="true"
                        ;;

                h)
                        echo "Usage:"
                        echo "args.sh -h "
                        echo "args.sh -e "
                        echo ""
                        echo "   -e     to execute echo \"hello world\""
                        echo "   -h     help (this output)"
                        exit 0
                        ;;

        esac
done

if [ $ECHO = "true" ]
then
        echo "Hello world";
fi

click here for source

2 Comments

This is the true solution since it allows any option in any order
in the h) option I suppose you should also replace args.sh by $0
4

Yes, you can use the shell built-in getopts, or the stand-alone getopt for this purpose.

Comments

0

You can iterate over the arguments to and read the options in any order. Here is an example. For a script using this code see - script example

#Example
OPTION_1=""
option_array[0]="1"
option_array[1]="2"

options="$@"


set_options(){
    prev_option=""

    for option in $options;
    do
        case $prev_option in
            "-t" )
                OPTION_1=$option
            ;;
            "-d" )
                option_array+=("$option")
            ;;
            "-g" )

                option_array_2+=("$option")
            ;;

        esac

        prev_option="$option"

    done

}

function test()
{
    set_options

    echo $OPTION_1
    echo ${option_array[*]}
    echo ${option_array_2[*]}

}


test

1 Comment

Why do you use prev_option why not just use option
0

Use getopts.

Here's a demo:

#!/bin/bash
#
# Example of using options and arguments in shell scripts
#

while getopts ab OPTION 
do
  case $OPTION in
  a)
     aflag=1
     ;;
  b)
     bflag=1
     ;;
  esac
done

# print options
echo "Option a: $aflag"
echo "Option b: $bflag"

# print arguments
echo "Arguments:"
shift $(($OPTIND - 1))
for arg in $*
do
  echo $arg
done

Usage:

./print_options.sh -ba
# Option a: 1
# Option b: 1
# Arguments:

./print_options.sh -a
# Option a: 1
# Option b: 
# Arguments:

./print_options.sh -ab xx yyy
# Option a: 1
# Option b: 1
# Arguments:
# xx
# yyy

The function throws an error if you use an invalid option:

./print_options.sh -a -c       
# ./print_options.sh: illegal option -- c
# Option a: 1
# Option b:  
# Arguments:

You could handle invalid options with

while getopts ab OPTION
do
  case $OPTION in
  a)
     aflag=1
     ;;
  b)
     bflag=1
     bval="$OPTARG"
     ;;
  \?) 
     exit
     ;;
  esac
done

The getopts utility provides a useful feature: it automatically increments the OPTIND (options index) variable. This allows you to differentiate between command-line options and positional arguments.

Additionally, getopts simplifies the parsing of option arguments. If an option is followed by a colon (:) in the options string, the next command-line token/string is treated as the argument for that option.

#!/bin/bash
#
# Example of using options in scripts
#

while getopts ab: OPTION 
do
  case $OPTION in
  a)
     aflag=1
     ;;
  b)
     bflag=1
     bval="$OPTARG"
     ;;
  esac
done

# print options
echo "Option a: $aflag"
echo "Option b: $bflag"
echo "Option b's argument: $bval"

# print arguments
echo "Arguments:"
shift $(($OPTIND - 1))
for arg in $*
do
  echo $arg
done

Test it:

./print_options.sh -a -b "arg for b" xx 
# Option a: 1
# Option b: 1
# Option b's argument: arg for b
# Arguments:
# xx

The only limitation is that the order of options and arguments matters; options must precede arguments when using getopts, as demonstrated in the following example:

./print_options.sh -b xx yyy -a
# Option a: 
# Option b: 1
# Arguments:
# xx
# yyy
# -a

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.