Instantly share code, notes, and snippets.

Embed
What would you like to do?
a simple way to parse shell script arguments
#!/bin/sh
#
# a simple way to parse shell script arguments
#
# please edit and use to your hearts content
#
ENVIRONMENT="dev"
DB_PATH="/data/db"
function usage()
{
echo "if this was a real script you would see something useful here"
echo ""
echo "./simple_args_parsing.sh"
echo "\t-h --help"
echo "\t--environment=$ENVIRONMENT"
echo "\t--db-path=$DB_PATH"
echo ""
}
while [ "$1" != "" ]; do
PARAM=`echo $1 | awk -F= '{print $1}'`
VALUE=`echo $1 | awk -F= '{print $2}'`
case $PARAM in
-h | --help)
usage
exit
;;
--environment)
ENVIRONMENT=$VALUE
;;
--db-path)
DB_PATH=$VALUE
;;
*)
echo "ERROR: unknown parameter \"$PARAM\""
usage
exit 1
;;
esac
shift
done
echo "ENVIRONMENT is $ENVIRONMENT";
echo "DB_PATH is $DB_PATH";
@hypersoft

This comment has been minimized.

hypersoft commented Jan 26, 2013

👎 You've complicated a really simple task..

printfx() {

    TEMP=`getopt -o hbrkwels:c:v:f:p: --long help,write,keep,reset,bold,format:,script:,color:,print: -n "$FUNCNAME" -- "$@"`

    if [ $? != 0 ] ; then return 1 ; fi

    eval set -- "$TEMP";

    local format='%s\n' escape='-E' line='-n' script clear='tput sgr0';

    while [[ ${1:0:1} == - ]]; do
        [[ $1 =~ ^-h|--help ]] && {
            cat <<-EOF
            USAGE: $FUNCNAME [OPTIONS] [TEXT]

            OPTIONS

              -s  Adds a line of text to tput script
              -c  Adds a line of text to tput script that sets the foreground
                  color
              -b  Adds a line of text to tput script that activates emboldened
                  text
              -f  Sets the final printf format
              -w  Forces an immediate write of tput script
              -p  Immediately prints data to standard out
              -e  Enabled backslash interpretation in immediate print operations
              -l  Enables line output in immediate print operations
              -k  disables terminal reset on return
              -r  Forces an immediate reset of terminal settings
              -v  Adds multiple lines of script from a shell variable label

              --script  Same as -s
              --color   Same as -c
              --bold    Same as -b
              --format  Same as -f
              --write   Same as -w
              --print   Same as -p
              --keep    Same as -k
              --reset   Same as -r

            EOF
            return;
        };

        [[ $1 == -- ]] && { shift; break; };
        [[ $1 == -l ]] && { line=''; shift 1; continue; };
        [[ $1 =~ ^-s|--script$ ]] && { script+="$2"$'\n'; shift 2; continue; };
        [[ $1 =~ ^-c|--color$ ]] && { script+="setf $2"$'\n'; shift 2; continue; };
        [[ $1 =~ ^-b|--bold$ ]] && { script+="bold"$'\n'; shift 1; continue; };
        [[ $1 =~ ^-f|--format$ ]] && { format="${2}"; shift 2; continue; };
        [[ $1 =~ ^-w|--write$ ]] && { tput -S <<<"$script"; script=''; shift 1; continue; };
        [[ $1 =~ ^-p|--print$ ]] && { echo $escape $line "${2}"; escape='-E' line='-n'; shift 2; continue; };
        [[ $1 =~ ^-k|--keep$ ]] && { clear='true'; shift 1; continue; };
        [[ $1 =~ ^-r|--reset$ ]] && { tput sgr0; shift 1; continue; };
        [[ $1 =~ ^-v ]] && { script+="${!2}"$'\n'; shift 2; continue; };
        [[ $1 =~ ^-e ]] && { escape=$1; shift 1; continue; };

        break;
    done

    echo $format;
    tput -S <<<"$script";
    (( $# )) && printf "$format" "$@";
    $clear;

}
@perepechaev

This comment has been minimized.

perepechaev commented Jul 18, 2013

I think that it is better to replace https://gist.github.com/jehiah/855086#file-simple_args_parsing-sh-L26

VALUE=`echo $1 | sed 's/^[^=]*=//g'`

sample:
/bin/sh myscript --host=localhost --uri="/some/uri/?debug=1"

@geoff-codes

This comment has been minimized.

geoff-codes commented Nov 2, 2013

@hypersoft: I really don't see how your code is any simpler... it is much less readable; and significantly less portable. This gist would appear to be intended as a shell script; not a bash script; and while the original does have one bashism, it seems like a trivial oversight (should be just usage() rather than function usage(). Your code includes using GNU getopt; herestrings, and many, many bash-only features that make it completely unsuited for any type of portable shell script.

@brunodix

This comment has been minimized.

brunodix commented Feb 4, 2014

Thanks, works even on Git Bash on Windows.

@cfollet

This comment has been minimized.

cfollet commented May 24, 2016

Thank you for this. But why you didn't use$0 in order to retrieve the script name ?

@diemol

This comment has been minimized.

diemol commented Sep 30, 2016

Shouldn't line https://gist.github.com/jehiah/855086#file-simple_args_parsing-sh-L44 be shift 2?
I am trying it and the parameters are shifted one by one, when (I think) the loop expects them to move two by two.

Anyway, thanks for this, saves a bunch of time 👍

@matejak

This comment has been minimized.

matejak commented Dec 7, 2016

Better than writing the parsing code is having one generated and that's the reason why I have started the argbash project here on Github. Keeping the usage function up-to-date and having support for positional arguments are some of the obvious benefits.
There is even an online bash 3.0+ compatible parsing code generator at https://argbash.io/generate

@stancufm

This comment has been minimized.

stancufm commented May 12, 2017

I've started the run-sections project if you need more than just parsing arguments. With run-sections you can chose what part of you code do you want to run and much more. You can simply mark sections inside your script and run just that sections. If you are interested on this idea, please have a look on https://github.com/stancufm/run-sections . It's very easy to work with this function.

@tchalvak

This comment has been minimized.

tchalvak commented Jun 29, 2017

./simple_args_parsing.sh
./simple_args_parsing.sh: 13: ./simple_args_parsing.sh: Syntax error: "(" unexpected

Soo... not great.

@gperreymond

This comment has been minimized.

gperreymond commented Sep 28, 2017

Hotfix this

function usage()
{

With :

usage() {
@bormansquirrel

This comment has been minimized.

bormansquirrel commented Apr 9, 2018

Nice gist conception!
Just a small detail, add -e to echo commands in the help menu, so it will format special tab characters ...

@bestjejust

This comment has been minimized.

bestjejust commented May 31, 2018

echo "\t-h --help"

shouldn't it be echo -e? Otherwise it prints \t in my case.

Or better use printf?

@elliotboney

This comment has been minimized.

elliotboney commented Jul 17, 2018

@geoff-codes thanks for the snippet! @hypersoft's solution was hella less readable

@Mrcooder

This comment has been minimized.

Mrcooder commented Sep 11, 2018

Thank you a lot

@Mrcooder

This comment has been minimized.

Mrcooder commented Sep 11, 2018

@gperreymond is right, without function keyword is better than with it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment