7

I want to write a command line tool like git which will follow the POSIX standards. It will take the options like --help or -h , --version ..etc. But i am not getting how to do it. Can anybody tell me how to do this using bash scripting. Please help me. This is something very new to me.

Example : if the name of my tool is Check-code then i want to use the tool like ;

Check-code --help 

or

Check-code --version
1

3 Answers 3

9

So far as I know, "long options", like --help and --version are not POSIX standard, but GNU standard. For command-line utilities the POSIX standard says:

The arguments that consist of hyphens and single letters or digits, such as 'a', are known as "options" (or, historically, "flags").

To support POSIX short options options it is worth getting to know getopts (there are tutorials on the web), but it does not support GNU long options.

For long options you have to roll your own:

filename=default
while (( $# > 0 ))
do
    opt="$1"
    shift

    case $opt in
    --help)
        helpfunc
        exit 0
        ;;
    --version)
        echo "$0 version $version"
        exit 0
        ;;
    --file)  # Example with an operand
        filename="$1"
        shift
        ;;
    --*)
        echo "Invalid option: '$opt'" >&2
        exit 1
        ;;
    *)
        # end of long options
        break;
        ;;
   esac

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

4 Comments

I think this can be one of the way to achieve the long options. Using getopt can we make it short and working for both short and long options
@user1497818: very difficult, I can't see a way of using getopts with long options. You might be better off using Perl and Getopt::Long perldoc.perl.org/Getopt/Long.html
You could detect a single dash in the case and pass $opt and $1 (in case there is an argument to the option) to getopts for it to handle. The only advantage gained is the ability to handle multiple single-letter options passed as a group (e.g. -ine == -i -n -e). I've never had anyone request that ability for any tool I've written so I've never bothered to support it.
for long/short, just use | i.e. version|-v|--version)
4

You can use the 'getopts' builtin, like so:

#!/bin/bash

# Parse arguments
usage() {
    echo "Usage: $0 [-h] [-v] [-f FILE]"
    echo "  -h  Help. Display this message and quit.
    echo "  -v  Version. Print version number and quit.
    echo "  -f  Specify configuration file FILE."
    exit
}

optspec="hvf:"
while getopts "$optspec" optchar
do
    case "${optchar}" in
        h)
            usage
            ;;
        v)
            version
            ;;
        f)
            file=${OPTARG}
            ;;
        *)
            usage
            ;;
    esac
done

This only works for single character options, not for long options like -help or --help. In practice, I've never found that this is a significant restriction; any script which is complex enough to require long options is probably something that I would write in a different language.

Comments

0

There is probably a better way to do this, but here is what I find useful: Each argument is represented by a variable in BASH. The first argument is $1. The second is $2, and so on. Match an option string with the first argument, and if it matches run some code accordingly.

Example:

#!/bin/bash
if [ $1 == "--hello" ] 
    then
        echo "Hello"
    else
        echo "Goodbye"
fi

If you code in C or C++, then use the **argv variable. **argv is a double pointer that holds a list of all arguments passed to the program (with argv[0] being the program name).

2 Comments

thanks for the reply.I think we can use the bash command "getopt" . Can you propose the solution of above using that. But i don't know whether it works for both "-h" and "--help" kind of formats
If using the Bourne shell style test ([) you should quote the "$1". Using [[ does not require quotes around the variable (but still need quotes around a literal containing white-space).

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.