command-line argument check - Bash에서 명령 행 인수를 구문 분석하려면 어떻게해야합니까?





14 Answers

아무 대답도 향상된 getopt를 언급하지 않는다. 그리고 가장 많이 -⁠vfd 대답 은 오도 된 것입니다 : -⁠vfd 스타일의 짧은 옵션 (OP에 의해 요구됨), 위치 인수 (OP에 의해 요청 된) 이후의 옵션을 무시하고 구문 분석 오류를 무시합니다. 대신 :

  • util-linux 또는 이전의 GNU glibc에서 향상된 getopt 를 사용하십시오 . 1
  • getopt_long() 은 GNU glibc의 C 함수와 함께 작동합니다.
  • 모든 유용한 구분 기능이 있습니다 (다른 기능은 가지고 있지 않습니다).
    • 공백을 처리하고, 인자와 2 인자의 인자를 인용한다.
    • 마지막 옵션을 처리 할 수 ​​있습니다 : script.sh -o outFile file1 file2 -v
    • = 스타일의 긴 옵션을 허용합니다 : script.sh --outfile=fileOut --infile fileIn
  • GNU 시스템이 이것을 놓치지 않았다는 것을 이미 예전에 알았습니다 (예를 들어, 어떤 리눅스에도 있습니다).
  • getopt --test → return value 4로 그 존재를 테스트 할 수있다.
  • 다른 getopt 또는 쉘 내장 getopts 는 사용이 제한적입니다.

다음 호출

myscript -vfd ./foo/bar/someFile -o /fizz/someOtherFile
myscript -v -f -d -o/fizz/someOtherFile -- ./foo/bar/someFile
myscript --verbose --force --debug ./foo/bar/someFile -o/fizz/someOtherFile
myscript --output=/fizz/someOtherFile ./foo/bar/someFile -vfd
myscript ./foo/bar/someFile -df -v --output /fizz/someOtherFile

모두 돌아온다.

verbose: y, force: y, debug: y, in: ./foo/bar/someFile, out: /fizz/someOtherFile

다음과 같은 myscript

#!/bin/bash
# saner programming env: these switches turn some bugs into errors
set -o errexit -o pipefail -o noclobber -o nounset

! getopt --test > /dev/null 
if [[ ${PIPESTATUS[0]} -ne 4 ]]; then
    echo "I’m sorry, `getopt --test` failed in this environment."
    exit 1
fi

OPTIONS=dfo:v
LONGOPTS=debug,force,output:,verbose

# -use ! and PIPESTATUS to get exit code with errexit set
# -temporarily store output to be able to check for errors
# -activate quoting/enhanced mode (e.g. by writing out “--options”)
# -pass arguments only via   -- "$@"   to separate them correctly
! PARSED=$(getopt --options=$OPTIONS --longoptions=$LONGOPTS --name "$0" -- "$@")
if [[ ${PIPESTATUS[0]} -ne 0 ]]; then
    # e.g. return value is 1
    #  then getopt has complained about wrong arguments to stdout
    exit 2
fi
# read getopt’s output this way to handle the quoting right:
eval set -- "$PARSED"

d=n f=n v=n outFile=-
# now enjoy the options in order and nicely split until we see --
while true; do
    case "$1" in
        -d|--debug)
            d=y
            shift
            ;;
        -f|--force)
            f=y
            shift
            ;;
        -v|--verbose)
            v=y
            shift
            ;;
        -o|--output)
            outFile="$2"
            shift 2
            ;;
        --)
            shift
            break
            ;;
        *)
            echo "Programming error"
            exit 3
            ;;
    esac
done

# handle non-option arguments
if [[ $# -ne 1 ]]; then
    echo "$0: A single input file is required."
    exit 4
fi

echo "verbose: $v, force: $f, debug: $d, in: $1, out: $outFile"

1 향상된 getopt는 Cygwin을 포함한 대부분의 "bash 시스템"에서 사용할 수 있습니다. OS X에서 brew install gnu-getopt 또는 sudo port install getopt 시도
2 POSIX exec() 규칙은 명령 행 인수에서 바이너리 NULL을 전달할 수있는 확실한 방법이 없습니다. 그 바이트들은 끝내 인수를 끝내지 않는다.
1997 년 또는 그 이전에 발표 된 3 개의 첫 번째 버전 (나는 1997 년까지만 추적했다)

parsing get parameter

말하자면,이 줄로 호출되는 스크립트가 있습니다.

./myscript -vfd ./foo/bar/someFile -o /fizz/someOtherFile

또는이 하나 :

./myscript -v -f -d -o /fizz/someOtherFile ./foo/bar/someFile 

$v , $f , 및 $d 이 모두 true 로 설정되고 $outFile/fizz/someOtherFile 과 같아 지도록이 구문 분석을 허용하는 방법은 무엇입니까?




getopt() / getopts() 가 좋은 옵션입니다. here 에서 도난당했습니다.

이 미니 스크립트에는 "getopt"의 간단한 사용법이 표시됩니다.

#!/bin/bash
echo "Before getopt"
for i
do
  echo $i
done
args=`getopt abc:d $*`
set -- $args
echo "After getopt"
for i
do
  echo "-->$i"
done

우리가 말한 것은 -a, -b, -c 또는 -d 중 하나는 허용되지만 -c 뒤에는 인수가옵니다 ( "c :"는이를 나타냄).

우리가 이것을 "g"라고 부르고 그것을 시험해 보면 :

bash-2.05a$ ./g -abc foo
Before getopt
-abc
foo
After getopt
-->-a
-->-b
-->-c
-->foo
-->--

우리는 두 개의 인수로 시작하고, "getopt"는 옵션을 분리하고 각 인수를 자체 인수에 넣습니다. 또한 "-"가 추가되었습니다.




보다 간결한 방법

script.sh

#!/bin/bash

while [[ "$#" > 0 ]]; do case $1 in
  -d|--deploy) deploy="$2"; shift;;
  -u|--uglify) uglify=1;;
  *) echo "Unknown parameter passed: $1"; exit 1;;
esac; shift; done

echo "Should deploy? $deploy"
echo "Should uglify? $uglify"

용법:

./script.sh -d dev -u

# OR:

./script.sh --deploy dev --uglify



내 답변은 주로 Bruno Bronosky의 대답을 기반으로하지만, 나는 꽤 자주 사용하는 두 가지 순수한 bash 구현을 매시 켰다 .

# As long as there is at least one more argument, keep looping
while [[ $# -gt 0 ]]; do
    key="$1"
    case "$key" in
        # This is a flag type option. Will catch either -f or --foo
        -f|--foo)
        FOO=1
        ;;
        # Also a flag type option. Will catch either -b or --bar
        -b|--bar)
        BAR=1
        ;;
        # This is an arg value type option. Will catch -o value or --output-file value
        -o|--output-file)
        shift # past the key and to the value
        OUTPUTFILE="$1"
        ;;
        # This is an arg=value type option. Will catch -o=value or --output-file=value
        -o=*|--output-file=*)
        # No need to shift here since the value is part of the same string
        OUTPUTFILE="${key#*=}"
        ;;
        *)
        # Do whatever you want with extra options
        echo "Unknown option '$key'"
        ;;
    esac
    # Shift after checking all the cases to get the next option
    shift
done

이렇게하면 공백으로 구분 된 옵션 / 값과 동일한 정의 값을 가질 수 있습니다.

따라서 다음을 사용하여 스크립트를 실행할 수 있습니다.

./myscript --foo -b -o /fizz/file.txt

만큼 잘:

./myscript -f --bar -o=/fizz/file.txt

둘 다 동일한 최종 결과를 가져야합니다.

PROS :

  • -arg = 값과 -arg 값을 모두 허용합니다.

  • bash에서 사용할 수있는 arg 이름으로 작업

    • 의미 -a 또는 -arg 또는 -arg 또는 -arg 또는 무엇이든
  • 순수한 배쉬. getopt 또는 getopts를 배우거나 사용할 필요가 없습니다.

단점 :

  • args를 결합 할 수 없습니다.

    • 의미 없음 -abc. -a -b -c를 ​​수행해야합니다.

이것들은 내 머리 꼭대기에서 생각할 수있는 유일한 장점 / 단점들입니다.




나는 이것을 사용하기에 충분히 간단하다고 생각한다.

#!/bin/bash
#

readopt='getopts $opts opt;rc=$?;[ $rc$opt == 0? ]&&exit 1;[ $rc == 0 ]||{ shift $[OPTIND-1];false; }'

opts=vfdo:

# Enumerating options
while eval $readopt
do
    echo OPT:$opt ${OPTARG+OPTARG:$OPTARG}
done

# Enumerating arguments
for arg
do
    echo ARG:$arg
done

호출 예제 :

./myscript -v -do /fizz/someOtherFile -f ./foo/bar/someFile
OPT:v 
OPT:d 
OPT:o OPTARG:/fizz/someOtherFile
OPT:f 
ARG:./foo/bar/someFile



getopts는 # 1을 설치하고 # 2를 동일한 플랫폼에서 실행하려는 경우 훌륭하게 작동합니다. OSX와 Linux는 (예를 들어)이 점에서 다르게 행동합니다.

다음은 equals, non-equals 및 boolean 플래그를 지원하는 (getopts가 아닌) 솔루션입니다. 예를 들어 다음과 같이 스크립트를 실행할 수 있습니다.

./script --arg1=value1 --arg2 value2 --shouldClean

# parse the arguments.
COUNTER=0
ARGS=("$@")
while [ $COUNTER -lt $# ]
do
    arg=${ARGS[$COUNTER]}
    let COUNTER=COUNTER+1
    nextArg=${ARGS[$COUNTER]}

    if [[ $skipNext -eq 1 ]]; then
        echo "Skipping"
        skipNext=0
        continue
    fi

    argKey=""
    argVal=""
    if [[ "$arg" =~ ^\- ]]; then
        # if the format is: -key=value
        if [[ "$arg" =~ \= ]]; then
            argVal=$(echo "$arg" | cut -d'=' -f2)
            argKey=$(echo "$arg" | cut -d'=' -f1)
            skipNext=0

        # if the format is: -key value
        elif [[ ! "$nextArg" =~ ^\- ]]; then
            argKey="$arg"
            argVal="$nextArg"
            skipNext=1

        # if the format is: -key (a boolean flag)
        elif [[ "$nextArg" =~ ^\- ]] || [[ -z "$nextArg" ]]; then
            argKey="$arg"
            argVal=""
            skipNext=0
        fi
    # if the format has not flag, just a value.
    else
        argKey=""
        argVal="$arg"
        skipNext=0
    fi

    case "$argKey" in 
        --source-scmurl)
            SOURCE_URL="$argVal"
        ;;
        --dest-scmurl)
            DEST_URL="$argVal"
        ;;
        --version-num)
            VERSION_NUM="$argVal"
        ;;
        -c|--clean)
            CLEAN_BEFORE_START="1"
        ;;
        -h|--help|-help|--h)
            showUsage
            exit
        ;;
    esac
done



이것은 getopts가 스택 어딘가에 동시에 실행되는 것을 피하기 위해 함수에서하는 방법입니다 :

function waitForWeb () {
   local OPTIND=1 OPTARG OPTION
   local host=localhost port=8080 proto=http
   while getopts "h:p:r:" OPTION; do
      case "$OPTION" in
      h)
         host="$OPTARG"
         ;;
      p)
         port="$OPTARG"
         ;;
      r)
         proto="$OPTARG"
         ;;
      esac
   done
...
}



나는 다음을 허용하는 옵션 구문 분석의 제 버전을 제공하고 싶습니다.

-s p1
--stage p1
-w somefolder
--workfolder somefolder
-sw p1 somefolder
-e=hello

또한 이것을 허용합니다 (원하지 않을 수 있음).

-s--workfolder p1 somefolder
-se=hello p1
-swe=hello p1 somefolder

옵션에 =을 사용하려면 사용 전에 결정해야합니다. 이것은 코드를 깨끗하게 유지하는 것입니다 (ish).

while [[ $# > 0 ]]
do
    key="$1"
    while [[ ${key+x} ]]
    do
        case $key in
            -s*|--stage)
                STAGE="$2"
                shift # option has parameter
                ;;
            -w*|--workfolder)
                workfolder="$2"
                shift # option has parameter
                ;;
            -e=*)
                EXAMPLE="${key#*=}"
                break # option has been fully handled
                ;;
            *)
                # unknown option
                echo Unknown option: $key #1>&2
                exit 10 # either this: my preferred way to handle unknown options
                break # or this: do this to signal the option has been handled (if exit isn't used)
                ;;
        esac
        # prepare for next option in this key, if any
        [[ "$key" = -? || "$key" == --* ]] && unset key || key="${key/#-?/-}"
    done
    shift # option(s) fully processed, proceed to next input argument
done



위치 및 플래그 기반 인수의 혼합

--param = arg (등호 구분)

위치 인수 사이에 자유롭게 깃발 섞기 :

./script.sh dumbo 127.0.0.1 --environment=production -q -d
./script.sh dumbo --environment=production 127.0.0.1 --quiet -d

상당히 간결한 접근 방식으로 달성 될 수 있습니다.

# process flags
pointer=1
while [[ $pointer -le $# ]]; do
   param=${!pointer}
   if [[ $param != "-"* ]]; then ((pointer++)) # not a parameter flag so advance pointer
   else
      case $param in
         # paramter-flags with arguments
         -e=*|--environment=*) environment="${param#*=}";;
                  --another=*) another="${param#*=}";;

         # binary flags
         -q|--quiet) quiet=true;;
                 -d) debug=true;;
      esac

      # splice out pointer frame from positional list
      [[ $pointer -gt 1 ]] \
         && set -- ${@:1:((pointer - 1))} ${@:((pointer + 1)):$#} \
         || set -- ${@:((pointer + 1)):$#};
   fi
done

# positional remain
node_name=$1
ip_address=$2

--param arg (공백으로 구분)

믹스 --flag=value--flag value스타일 을 지정하지 않는 것이 일반적으로 더 명확 합니다.

./script.sh dumbo 127.0.0.1 --environment production -q -d

이 책은 읽기에 조금 까다 롭지 만 여전히 유효합니다.

./script.sh dumbo --environment production 127.0.0.1 --quiet -d

출처

# process flags
pointer=1
while [[ $pointer -le $# ]]; do
   if [[ ${!pointer} != "-"* ]]; then ((pointer++)) # not a parameter flag so advance pointer
   else
      param=${!pointer}
      ((pointer_plus = pointer + 1))
      slice_len=1

      case $param in
         # paramter-flags with arguments
         -e|--environment) environment=${!pointer_plus}; ((slice_len++));;
                --another) another=${!pointer_plus}; ((slice_len++));;

         # binary flags
         -q|--quiet) quiet=true;;
                 -d) debug=true;;
      esac

      # splice out pointer frame from positional list
      [[ $pointer -gt 1 ]] \
         && set -- ${@:1:((pointer - 1))} ${@:((pointer + $slice_len)):$#} \
         || set -- ${@:((pointer + $slice_len)):$#};
   fi
done

# positional remain
node_name=$1
ip_address=$2



bash-modules 모듈의 "arguments" bash-modules

예:

#!/bin/bash
. import.sh log arguments

NAME="world"

parse_arguments "-n|--name)NAME;S" -- "$@" || {
  error "Cannot parse command line."
  exit 1
}

info "Hello, $NAME!"



getopt [s]가없는 또 다른 해결책, POSIX, 오래된 유닉스 스타일

Bruno Bronosky 와 비슷한 솔루션은 여기에 게시되었습니다getopt(s) .

내 솔루션의 주요 차별화 된 기능 tar -xzf foo.tar.gz은 동일한 옵션을 함께 연결하는 것 입니다 tar -x -z -f foo.tar.gz. 그리고 그냥 좋아 tar, ps최고의 하이픈이 짧은 옵션의 블록에 대한 선택 사항 등 (그러나 이것은 쉽게 변경할 수 있습니다). 긴 옵션도 지원됩니다 (그러나 블록이 1로 시작할 때 두 개의 선행 하이픈이 필요합니다).

예제 옵션이있는 코드

#!/bin/sh

echo
echo "POSIX-compliant getopt(s)-free old-style-supporting option parser from phk@[se.unix]"
echo

print_usage() {
  echo "Usage:

  $0 {a|b|c} [ARG...]

Options:

  --aaa-0-args
  -a
    Option without arguments.

  --bbb-1-args ARG
  -b ARG
    Option with one argument.

  --ccc-2-args ARG1 ARG2
  -c ARG1 ARG2
    Option with two arguments.

" >&2
}

if [ $# -le 0 ]; then
  print_usage
  exit 1
fi

opt=
while :; do

  if [ $# -le 0 ]; then

    # no parameters remaining -> end option parsing
    break

  elif [ ! "$opt" ]; then

    # we are at the beginning of a fresh block
    # remove optional leading hyphen and strip trailing whitespaces
    opt=$(echo "$1" | sed 's/^-\?\([a-zA-Z0-9\?-]*\)/\1/')

  fi

  # get the first character -> check whether long option
  first_chr=$(echo "$opt" | awk '{print substr($1, 1, 1)}')
  [ "$first_chr" = - ] && long_option=T || long_option=F

  # note to write the options here with a leading hyphen less
  # also do not forget to end short options with a star
  case $opt in

    -)

      # end of options
      shift
      break
      ;;

    a*|-aaa-0-args)

      echo "Option AAA activated!"
      ;;

    b*|-bbb-1-args)

      if [ "$2" ]; then
        echo "Option BBB with argument '$2' activated!"
        shift
      else
        echo "BBB parameters incomplete!" >&2
        print_usage
        exit 1
      fi
      ;;

    c*|-ccc-2-args)

      if [ "$2" ] && [ "$3" ]; then
        echo "Option CCC with arguments '$2' and '$3' activated!"
        shift 2
      else
        echo "CCC parameters incomplete!" >&2
        print_usage
        exit 1
      fi
      ;;

    h*|\?*|-help)

      print_usage
      exit 0
      ;;

    *)

      if [ "$long_option" = T ]; then
        opt=$(echo "$opt" | awk '{print substr($1, 2)}')
      else
        opt=$first_chr
      fi
      printf 'Error: Unknown option: "%s"\n' "$opt" >&2
      print_usage
      exit 1
      ;;

  esac

  if [ "$long_option" = T ]; then

    # if we had a long option then we are going to get a new block next
    shift
    opt=

  else

    # if we had a short option then just move to the next character
    opt=$(echo "$opt" | awk '{print substr($1, 2)}')

    # if block is now empty then shift to the next one
    [ "$opt" ] || shift

  fi

done

echo "Doing something..."

exit 0

예제 사용법은 아래 예제를 참조하십시오.

인수가있는 옵션의 위치

그 가치가있는 무엇을 위해 인자가있는 옵션은 마지막 옵션이 아닙니다 (오직 긴 옵션 만 필요합니다). 예를 들어 tar(적어도 일부 구현에서는) f파일 이름이 ( tar xzf bar.tar.gz작동하지만 실제로 tar xfz bar.tar.gz는 안됨) 따르기 때문에 옵션을 마지막으로 사용해야 하는 반면 , 여기서는 그렇지 않습니다 (이후 예제 참조).

인수가있는 여러 옵션

또 다른 보너스로 옵션 매개 변수는 필요한 옵션이있는 매개 변수에 의해 옵션 순서대로 사용됩니다. 명령 줄 abc XYZ(또는 -abc XYZ)을 사용하여 여기 내 스크립트의 출력을보십시오 .

Option AAA activated!
Option BBB with argument 'X' activated!
Option CCC with arguments 'Y' and 'Z' activated!

긴 옵션도 연결됨

또한 블록에서 마지막으로 발생하는 경우 옵션 블록에서 긴 옵션을 사용할 수도 있습니다. 따라서 다음 명령 줄은 모두 동일합니다 (옵션과 인수가 처리되는 순서 포함).

  • -cba ZYX
  • cba ZYX
  • -cb-aaa-0-args ZYX
  • -c-bbb-1-args ZYX -a
  • --ccc-2-args ZY -ba X
  • c ZY b X a
  • -c ZY -b X -a
  • --ccc-2-args ZY --bbb-1-args X --aaa-0-args

이 모든 것들은 다음과 같이 인도합니다 :

Option CCC with arguments 'Z' and 'Y' activated!
Option BBB with argument 'X' activated!
Option AAA activated!
Doing something...

이 솔루션에는 없습니다.

선택적 인수

선택적 인수를 갖는 옵션은 약간의 작업으로 가능해야합니다. 예를 들어, 하이픈없이 블록이 있는지를 찾는 것; 사용자는 선택적 매개 변수를 가진 매개 변수가있는 블록 다음의 모든 블록 앞에 하이픈을 넣어야합니다. 아마도 이것은 사용자와 의사 소통하기에 너무 복잡하기 때문에이 경우에는 하이픈을 모두 사용하는 것이 좋습니다.

가능한 여러 매개 변수로 상황이 더욱 복잡해집니다. 옵션이 옵션이 아닌지 여부를 결정함으로써 옵션을 현명하게하려고하지 않을 것을 권장합니다 (예를 들어, 옵션을 선택적 인수로 사용하는 등).

개인적으로 선택적 인수 대신 추가 옵션을 선호합니다.

등호와 함께 도입 된 옵션 인수

선택적 인수와 마찬가지로 (BTW, 다른 매개 변수 스타일의 장점 / 단점에 대해 논의하기위한 스레드가 있습니까?)하지만 당신이 이것을 원한다면 http://mywiki.wooledge.org/BashFAQ/035#Manual_loop 에서 한 것처럼 구현할 수 있습니다 http://mywiki.wooledge.org/BashFAQ/035#Manual_loop--long-with-arg=?*case 문을 입력하고 등호를 제거하십시오 (이것은 매개 변수 연결을 만드는 것이 가능한 노력이지만 BTW에서는 독자가 연습 문제로 남겨 두었습니다) "라고 말하면서 나를 처음부터 시작했다.

기타주의 사항

POSIX 호환, (예를 들어, 심지어 내가 처리했다 고대 비지 박스의 설정에서 작동 cut, headgetopts실종).




이 질문에 대한 가장 큰 대답은 제가 시도했을 때 약간 버그가있는 것 같았습니다 - 제가 여기있는 솔루션이 더 강력하다는 것을 알게되었습니다 :

boolean_arg=""
arg_with_value=""

while [[ $# -gt 0 ]]
do
key="$1"
case $key in
    -b|--boolean-arg)
    boolean_arg=true
    shift
    ;;
    -a|--arg-with-value)
    arg_with_value="$2"
    shift
    shift
    ;;
    -*)
    echo "Unknown option: $1"
    exit 1
    ;;
    *)
    arg_num=$(( $arg_num + 1 ))
    case $arg_num in
        1)
        first_normal_arg="$1"
        shift
        ;;
        2)
        second_normal_arg="$1"
        shift
        ;;
        *)
        bad_args=TRUE
    esac
    ;;
esac
done

# Handy to have this here when adding arguments to
# see if they're working. Just edit the '0' to be '1'.
if [[ 0 == 1 ]]; then
    echo "first_normal_arg: $first_normal_arg"
    echo "second_normal_arg: $second_normal_arg"
    echo "boolean_arg: $boolean_arg"
    echo "arg_with_value: $arg_with_value"
    exit 0
fi

if [[ $bad_args == TRUE || $arg_num < 2 ]]; then
    echo "Usage: $(basename "$0") <first-normal-arg> <second-normal-arg> [--boolean-arg] [--arg-with-value VALUE]"
    exit 1
fi



멋진 bash 도구를 작성하기 위해 bash 도우미를 작성했습니다.

프로젝트 홈 : https://gitlab.mbedsys.org/mbedsys/bashopts

예:

#!/bin/bash -ei

# load the library
. bashopts.sh

# Enable backtrace dusplay on error
trap 'bashopts_exit_handle' ERR

# Initialize the library
bashopts_setup -n "$0" -d "This is myapp tool description displayed on help message" -s "$HOME/.config/myapprc"

# Declare the options
bashopts_declare -n first_name -l first -o f -d "First name" -t string -i -s -r
bashopts_declare -n last_name -l last -o l -d "Last name" -t string -i -s -r
bashopts_declare -n display_name -l display-name -t string -d "Display name" -e "\$first_name \$last_name"
bashopts_declare -n age -l number -d "Age" -t number
bashopts_declare -n email_list -t string -m add -l email -d "Email adress"

# Parse arguments
bashopts_parse_args "$@"

# Process argument
bashopts_process_args

도움을 줄 것입니다 :

NAME:
    ./example.sh - This is myapp tool description displayed on help message

USAGE:
    [options and commands] [-- [extra args]]

OPTIONS:
    -h,--help                          Display this help
    -n,--non-interactive true          Non interactive mode - [$bashopts_non_interactive] (type:boolean, default:false)
    -f,--first "John"                  First name - [$first_name] (type:string, default:"")
    -l,--last "Smith"                  Last name - [$last_name] (type:string, default:"")
    --display-name "John Smith"        Display name - [$display_name] (type:string, default:"$first_name $last_name")
    --number 0                         Age - [$age] (type:number, default:0)
    --email                            Email adress - [$email_list] (type:string, default:"")

즐겨 :)




여기 가변 배열을 사용하여 Bruno Bronosky의 대답을 개선 한 솔루션이 있습니다.

매개 변수 위치를 혼합하고 옵션없이 순서를 유지하는 매개 변수 배열을 제공합니다.

#!/bin/bash

echo $@

PARAMS=()
SOFT=0
SKIP=()
for i in "$@"
do
case $i in
    -n=*|--skip=*)
    SKIP+=("${i#*=}")
    ;;
    -s|--soft)
    SOFT=1
    ;;
    *)
        # unknown option
        PARAMS+=("$i")
    ;;
esac
done
echo "SKIP            = ${SKIP[@]}"
echo "SOFT            = $SOFT"
    echo "Parameters:"
    echo ${PARAMS[@]}

출력 예 :

$ ./test.sh parameter -s somefile --skip=.c --skip=.obj
parameter -s somefile --skip=.c --skip=.obj
SKIP            = .c .obj
SOFT            = 1
Parameters:
parameter somefile



Related