Shell Script com opções

0

Estou escrevendo um script de shell que aceita no máximo duas opções. No entanto, tenho um problema. Você poderia me ajudar com isso? (Digamos que o nome deste script seja command .)

#!/bin/bash
PROGNAME=$(basename $0)
for OPT in "$@"
do
    echo "OPT: $OPT"
    case "$OPT" in
            '-p' | '--password' )
                    if [[ -z "$2" ]] || [[ "$2" =~ ^-+ ]]
                    then
                            echo "$PROGNAME: option requires an argument -- '$(echo $1 | sed 's/^-*//')'"
                            exit 2
                    fi
                    PASSWORD="$2"
                    shift 2
                    ;;
            '-u' | '--user' )
                    if [[ -z "$2" ]] || [[ "$2" =~ ^-+ ]]
                    then
                            echo "$PROGNAME: option requires an argument -- '$(echo $1 | sed 's/^-*//')'"
                            exit 2
                    fi
                    USER="$2"
                    shift 2
                    ;;
            * )
                    echo "$1"
                    echo "$PROGNAME: illigal option or argument -- '$(echo $1 | sed 's/^-*//')'"
                    exit 1
                    ;;
    esac
done
echo "GOOD"

Teste1

$./command 
GOOD

Teste2

$./command -u user
OPT: -u
OPT: user

command: illigal option or argument -- ''

(A quarta linha está vazia.)

Test3

$./command -u user -p passwd
OPT: -u
OPT: user
-p
command: illigal option or argument -- 'p'

Mesmas coisas acontecem a todos -u, --user, -p e --password. Eu tenho 3 perguntas.

1) Por que "OPT: user" aparece em test2 e test3?

2) Por que esse código causa erros se eu der uma opção a ele?

3) Como posso corrigir este código? Eu realmente aprecio sua ajuda!

    
por Nickel 27.08.2016 / 15:22

2 respostas

1

Sua expansão de "$@" acontece no início do ciclo for ; o shift dentro dele não terá impacto.

por exemplo

for a in "$@"
do
  echo OPTION: $a
  shift 2
done

Com isso:

$ bash x a b c d e f
OPTION: a
OPTION: b
OPTION: c
OPTION: d
OPTION: e
OPTION: f

Podemos ver que o shift não está fazendo nada

Em vez disso, você deseja reavaliar cada vez:

$ cat x             
while [ $# -gt 0 ]
do
  a="$1"
  echo OPTION: $a
  shift 2
done

$ bash x a b c d e f
OPTION: a
OPTION: c
OPTION: e

(Você precisa fazer um teste melhor que este; este código de exemplo nunca termina se você passar um número ímpar de argumentos porque o shift 2 falha)

    
por 27.08.2016 / 16:10
0

Eu uso um loop while / shift

#! /bin/bash
PROGNAME=$(basename $0)
while [ -n "$1" ]
do
  echo "OPT: $1"
  case "$1" in
    --user=* )
      if [[ "$1" =~ --user=(.+) ]]
      then
        USER=${BASH_REMATCH[1]}
      else
        echo "$PROGNAME: option requires an argument -- $1"
        exit 2
      fi
      ;;
    -u )
      if [ -z "$2" ]
      then
        echo "$PROGNAME: option requires an argument -- $1"
        exit 2
      fi
      USER="$2"
      shift
      ;;
    * )
      echo "$PROGNAME: illigal option or argument -- $1"
      exit 1
      ;;
  esac
  shift
done
[ -n "$USER" ] && echo "USER: $USER"
echo "GOOD"

Mas $USER é uma variável ruim, pois já está definida.

    
por 27.08.2016 / 16:19