81

I want to write a bash script which takes different arguments. It should be used like normal linux console programs:

my_bash_script -p 2 -l 5 -t 20

So the value 2 should be saved in a variable called pages and the parameter l should be saved in a variable called length and the value 20 should be saved in a variable time.

What is the best way to do this?

4
  • A variable in what? Parameters are related to the program you're runnning, not bash in this case. Does 'myProgramm' take parameters? Commented Aug 20, 2012 at 11:01
  • I want to write a program in bash which does this. Commented Aug 20, 2012 at 11:05
  • Note that unless you call the script using '.' (. myProgram -p2 -l 5 -t 20), the variables you set will only exist in myProgram, not the shell from which you call it. Commented Aug 20, 2012 at 12:51
  • It really seems to me that his intention is that myProgramm is a bash script. In which case getopts is correct. To avoid this confusion maybe myProgramm should be called my_bash_script. Hey what the heck I'll edit it Commented Oct 22, 2014 at 16:53

2 Answers 2

128

Use the getopts builtin:
here's a tutorial

pages=  length=  time=

while getopts p:l:t: opt; do
  case $opt in
  p)
      pages=$OPTARG
      ;;
  l)
      length=$OPTARG
      ;;
  t)
      time=$OPTARG
      ;;
  esac
done

shift $((OPTIND - 1))

shift $((OPTIND - 1)) shifts the command line parameters so that you can access possible arguments to your script, i.e. $1, $2, ...

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

2 Comments

mywiki.wooledge.org/BashFAQ/035 "getopt cannot handle empty arguments strings, or arguments with embedded whitespace. Please forget that it ever existed."
@Federico your confusing getopt and getopts... you should read your citation carefully (and please retract the down vote). You can also read here
13

Something along the lines of

pages=
length=
time=

while test $# -gt 0
do
    case $1 in
        -p)
            pages=$2
            shift
            ;;
        -l)
            length=$2
            shift
            ;;
        -t)
            time=$2
            shift
            ;;
        *)
            echo >&2 "Invalid argument: $1"
            ;;
    esac
    shift
done

4 Comments

-1, far better to use getopts
@StevenMackenzie, ...I'm not sure I can agree. If you look at BashFAQ #35, the manual-parsing example (of which this is further simplification) does rather a number of things that getopts simply can't. Following the practice is thus more flexible.
@StevenMackenzie, ...we're also in a world where folks have been spoiled by GNUisms such as being able to mix optional and positional arguments (barring the use of -- to explicitly signal end of the former and beginning of the latter alone). It's easy to do something like args+=( "$1" ) in a default case with a parser of this kind; with getopts, the cutoff at OPTIND is hard-and-fast.
Bash FAQ 35 (as above) tells me everything I need to know

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.