shell script arguments non positional

2019-03-21 17:05发布

Is there a way to feed non positional arguments to a shell script? Meaning explicitly specify some kind of flag?

. myscript.sh value1 value2
. myscript.sh -val1=value1 -val2=value2

标签: shell
5条回答
Emotional °昔
2楼-- · 2019-03-21 17:15
啃猪蹄的小仙女
3楼-- · 2019-03-21 17:18

Example:

#!/bin/bash
while getopts d:x arg
do
        case "$arg" in
                d) darg="$OPTARG";;
                x) xflag=1;;
                ?) echo >&2 "Usage: $0 [-x] [-d darg] files ..."; exit 1;;
        esac
done
shift $(( $OPTIND-1 ))

for file
do
        echo =$file=
done
查看更多
放荡不羁爱自由
4楼-- · 2019-03-21 17:19

Script has arguments as follows: - $0 - script name - $1, $2, $3.... - received arguments $* = all arguments, $# = number of arguments

Reference: http://famulatus.com/ks/os/solaris/item/203-arguments-in-sh-scripts.html

查看更多
Rolldiameter
5楼-- · 2019-03-21 17:30

You can use getopts, but I don't like it because it's complicated to use and it doesn't support long option names (not the POSIX version anyway).

I recommend against using environment variables. There's just too much risk of name collision. For example, if your script reacts differently depending on the value of the ARCH environment variable, and it executes another script that (unbeknownst to you) also reacts to the ARCH environment variable, then you probably have a hard-to-find bug that only shows up occasionally.

This is the pattern I use:

#!/bin/sh

usage() {
    cat <<EOF
Usage: $0 [options] [--] [file...]

Arguments:

  -h, --help
    Display this usage message and exit.

  -f <val>, --foo <val>, --foo=<val>
    Documentation goes here.

  -b <val>, --bar <val>, --bar=<val>
    Documentation goes here.

  --
    Treat the remaining arguments as file names.  Useful if the first
    file name might begin with '-'.

  file...
    Optional list of file names.  If the first file name in the list
    begins with '-', it will be treated as an option unless it comes
    after the '--' option.
EOF
}

# handy logging and error handling functions
log() { printf '%s\n' "$*"; }
error() { log "ERROR: $*" >&2; }
fatal() { error "$*"; exit 1; }
usage_fatal() { error "$*"; usage >&2; exit 1; }

# parse options
foo="foo default value goes here"
bar="bar default value goes here"
while [ "$#" -gt 0 ]; do
    arg=$1
    case $1 in
        # convert "--opt=the value" to --opt "the value".
        # the quotes around the equals sign is to work around a
        # bug in emacs' syntax parsing
        --*'='*) shift; set -- "${arg%%=*}" "${arg#*=}" "$@"; continue;;
        -f|--foo) shift; foo=$1;;
        -b|--bar) shift; bar=$1;;
        -h|--help) usage; exit 0;;
        --) shift; break;;
        -*) usage_fatal "unknown option: '$1'";;
        *) break;; # reached the list of file names
    esac
    shift || usage_fatal "option '${arg}' requires a value"
done
# arguments are now the file names
查看更多
The star\"
6楼-- · 2019-03-21 17:36

The easiest thing to do is pass them as environment variables:

$ val1=value1 val2=value2 ./myscript.sh

This doesn't work with csh variants, but you can use env if you are using such a shell.

查看更多
登录 后发表回答