Bash: Como usar enquanto shift; do..case $ 1 in

4

Estou trabalhando em um script bash e preciso implementar "opções". Como posso fazer isso com o bash?

meu objetivo é executar o script da seguinte maneira: /myscript.sh -d "/var/log/" -c "test"

o que eu tentei:

while shift; do
        case $1 in
                -d)
                        shift&&DIR="$1"||die
                ;;
                -c)
                        shift&&COMMAND="$1"||die
                ;;
        esac
done

echo "$DIR"
echo "$COMMAND"
    
por teslasimus 25.01.2013 / 15:43

4 respostas

5

Para expandir a resposta de @ choroba, aqui está um exemplo de como usar getopts :

# parse the flag options (and their arguments)
while getopts c:d: OPT; do
    case "$OPT" in
      d)
        DIR="$OPTARG" ;;
      c)
        COMMAND="$OPTARG" ;;
      [?])
        # got invalid option
        echo "Usage: $0 [-d directory] [-c command]" >&2
        exit 1 ;;
    esac
done

# get rid of the just-finished flag arguments
shift $(($OPTIND-1))

Observe que, depois de desativar os argumentos de sinalizador, todos os argumentos "regulares" permanecerão. Então, nesse ponto, você poderia lidar com eles (por exemplo, ... for arg in "$@"; do ... ) ou se o script não os pegasse apenas se você obtivesse algum ( if [ $# -gt 0 ]; then echo "Usage ... ).

    
por 25.01.2013 / 16:48
6

Seu erro é que você está mudando na parte superior do loop, jogando o primeiro argumento antes de examiná-lo. Isso é o que eu acho que você provavelmente quis dizer:

#!/bin/bash
while (( "$#" )); do
   case $1 in
      -d)
         shift&&DIR="$1"||die
         ;;
      -c)
         shift&&COMMAND="$1"||die
         ;;
   esac
   shift
done

echo "$DIR"
echo "$COMMAND"
    
por 25.01.2013 / 16:54
2

Como a choroba já disse, getopts é uma abordagem melhor.

No seu caso, você pode usar:

getopts c:d: d || die
DIR=$OPTARG
getopts c:d: c || die
COMMAND=$OPTARG

para alcançar o que você está tentando fazer com o loop while.

A string c:d: especifica as opções possíveis. O cólon significa que o comutador requer um argumento.

O problema com sua abordagem é que você chama shift antes de analisar o primeiro argumento, descartando-o no processo.

Para corrigir isso, altere o loop while para o seguinte:

while true; do
        case $1 in
                -d)
                        shift&&DIR="$1"||die
                ;;
                -c)
                        shift&&COMMAND="$1"||die
                ;;
        esac
        shift || break
done
    
por 25.01.2013 / 16:49
1

A abordagem usual é usar getopts .

    
por 25.01.2013 / 16:08

Tags