Menu de bash com vários parâmetros em uma linha

3

Eu pesquisei alguns dias e ainda não encontrei a resposta. Espero que você possa me apontar na direção certa.

Gostaria de saber como escrever um script bash com opções, que podem ser chamado em uma linha, como: script.sh -a -b -c . Parâmetros que não são escolhidos são ignorados.

Menu / opções devem ser como:

-a description: something
-b description: something else
-c description: something different
-d description: something..

existe alguma maneira de fazer isso?

    
por ticket 21.02.2015 / 16:54

2 respostas

7

A maneira usual de manipular switches e argumentos é com a função getopts . Em bash este é um builtin e você pode encontrar informações sobre ele na página man bash ( man bash ).

Essencialmente, você declara uma string que informa a getopts quais parâmetros esperar, e se eles devem ter um argumento. É getopts que lida com parâmetros agrupados (por exemplo, -abc sendo equivalente a -a -b -c ) e a análise da linha de comando. No final do processamento de getopts , você tem o restante da linha de comando para manipular como quiser.

Um segmento de script típico pode ser parecido com isso

ARG_A= FLAG_B= FLAG_C=
while getopts 'a:bc' OPT    # -a {argument}, -b, -c
do
    case "$OPT" in
        a)    ARG_A="$OPTARG" ;;
        b)    FLAG_B=yes ;;
        c)    FLAG_C=yes ;;
        *)    echo "ERROR: the options are -a {arg}, -b, -c" >&2; exit 1 ;;
    esac
done
shift $(($OPTIND - 1))

echo "Remaining command line: $*"

Você pode adicionar ? como uma opção de comando se quiser uma mensagem de uso legal . Lembre-se de que no bloco case você precisaria citar ou prefixar com uma barra invertida, de modo que seja tratado como um literal.

Se você deseja executá-lo com um shell diferente que não tenha o builtin, ou se deseja usar argumentos longos como --verbose em vez de apenas -v take uma olhada no utilitário getopt . Este não é um builtin, mas foi escrito para entregar na situação mais sofisticada.

    
por 21.02.2015 / 17:18
1

Você não precisa usar nenhum recurso específico do Bash para fazer isso:

#!/bin/sh
while true
do
    case "$1" in
        -a)  echo Saw -a!  ;;
        -b)  echo Saw -b!  ;;
        -c)  echo Saw -c!  ;;
        -?)  cat <<USAGE
usage: $0 [-a] [-b] [-c] args

    You cannot currently combine options, as with -ac.
USAGE
            exit 1
            ;;
        *)
            echo End of options!
            break;
            ;;
    esac

    shift       # toss current $1; we're done with it now
done

for p in "$@"
do
    echo "Non-option argument: '$p'"
done

Ao contrário do código na resposta do roaima , o meu é um código de script de shell portátil. Ele será executado em qualquer shell Unix do tipo Bourne, que remonta a aproximadamente 1980.

Acho que o manipulador -? responde ao seu requisito de "menu". A construção <<USAGE é chamada de heredoc .

    
por 21.02.2015 / 17:16