开发者

Parsing shell script arguments

$myscript.sh -host blah -user blah -pass blah
开发者_C百科

I want to pass arguments into it.

I'm used to doing $1, $2, $3....but I want to start naming them


There are lots of ways to parse arguments in sh. Getopt is good. Here's a simple script that parses things by hand:

#!/bin/sh
# WARNING: see discussion and caveats below
# this is extremely fragile and insecure

while echo $1 | grep -q ^-; do
    # Evaluating a user entered string!
    # Red flags!!!  Don't do this
    eval $( echo $1 | sed 's/^-//' )=$2
    shift
    shift
done

echo host = $host
echo user = $user
echo pass = $pass
echo args = $@

A sample run looks like:

$ ./a.sh -host foo -user me -pass secret some args
host = foo
user = me
pass = secret
args = some args

Note that this is not even remotely robust and massively open to security holes since the script eval's a string constructed by the user. It is merely meant to serve as an example for one possible way to do things. A simpler method is to require the user to pass the data in the environment. In a bourne shell (ie, anything that is not in the csh family):

$ host=blah user=blah pass=blah myscript.sh

works nicely, and the variables $host, $user, $pass will be available in the script.

#!/bin/sh
echo host = ${host:?host empty or unset}
echo user = ${user?user not set}
...


Here is a simple way to handle both long and short options:

while [[ $1 == -* ]]; do
    case "$1" in
      -h|--help|-\?) show_help; exit 0;;
      -v|--verbose) verbose=1; shift;;
      -f) if [[ $# > 1 && $2 != -* ]]; then
            output_file=$2; shift 2
          else 
            echo "-f requires an argument" 1>&2
            exit 1
          fi ;;
      --) shift; break;;
      -*) echo "invalid option: $1" 1>&2; show_help; exit 1;;
    esac
done

From How can I handle command-line arguments (options) to my script easily?


man getopt


I adopt above William Pursell example (with Dennis Williamson advice) for parameters in this format: script -param1=value1 -param2=value2 ...

Here is code with one-line arguments parser (save it in file 'script'):

#!/bin/bash

while echo $1 | grep ^- > /dev/null; do declare $( echo $1 | sed 's/-//g' | sed 's/=.*//g' | tr -d '\012')=$( echo $1 | sed 's/.*=//g' | tr -d '\012'); shift; done

echo host = $host
echo user = $user
echo pass = $pass

You call it like that:

script -host=aaa -user=bbb -pass=ccc

and result is

host = aaa
user = bbb
pass = ccc

Do someone know shorter code to parse arguments than this above?


Here's my approach:

host=""
user=""
pass=""
while [[ "$#" -gt 0 ]]; do
    case $1 in
        -h|--host) host="$2"; shift ;;
        -u|--user) user="$2"; shift ;;
        -p|--pass) pass="$2"; shift ;;
        *) echo "Unknown parameter passed: $1" ;;
    esac
    shift
done

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜