Bash: ajuda a aperfeiçoar uma função personalizada

1

Estou aprendendo Bash e escrevi uma função básica:

wsgc () {
    # Wipe the global variable value for 'getopts'.
    OPTIND=1;
    echo "git add -A";
    while getopts m:p option;
    do
        case "${option}"
        in
            m)
                COMMIT_MESSAGE=$OPTARG
                if [ "$COMMIT_MESSAGE" ]; then
                    echo "git commit -m \"$COMMIT_MESSAGE.\""
                else
                    echo "A commit message is required."
                    exit
                fi
                ;;
            p)
                echo "git push"
                exit
                ;;
            \?)
                echo "Invalid parameter."
                exit
                ;;
        esac
    done
}

No entanto, estou lutando com algumas coisas:

  1. o if em m) não está funcionando, pois se omitir o argumento, o Bash intercede e me expulsa da sessão;

    git add -A
    -bash: option requires an argument -- m
    Invalid parameter.
    logout
    Saving session...
    ...copying shared history...
    ...saving history...truncating history files...
    ...completed.
    

    [Processo concluído]

  2. Após a execução: wsgc -m "Yo!" -p , sou expulso da sessão.

    git add -A
    git commit -m "Yo."
    git push
    logout
    Saving session...
    ...copying shared history...
    ...saving history...truncating history files...
    ...completed.
    

    [Processo concluído]

Qualquer conselho seria muito apreciado.

    
por Wayne Smallman 31.08.2017 / 22:59

2 respostas

2

the if in m) isn't working, in that if I omit the argument, Bash intercedes and kicks me out of the session;

Você especifica getopts m:p option . O : após o m significa que você precisa de um argumento. Se você não fornecer, será um erro.

After running: wsgc -m "Yo!" -p, I get kicked out of the session.

O que você quer dizer com você ser expulso da sessão? A casca desaparece? Então, é porque você originou o script em vez de executá-lo.

Dito isto, recomendo usar getopt em vez de getopts .

    
por 31.08.2017 / 23:16
1
  • Se a opção -m não obtiver um valor, você exit do shell.
  • Se você usar a opção -p , você exit do shell.
  • Se você usar uma opção inválida, você exit do shell.

Em todos esses casos, você deve return em vez de exit e, em todos os casos, exceto o segundo, você deve return 1 (para sinalizar um erro). Além disso, as mensagens de erro devem ser redirecionadas para o fluxo de erro padrão com >&2 .

Aqui está uma versão da sua função com algumas modificações que fazem com que ela não produza nada, a menos que a análise da linha de comando tenha corrido bem.

wsgc () {
    local OPTIND=1
    local out=( "git add -A" )

    while getopts 'm:p' opt; do
        case "$opt" in
            m)  out+=( "git commit -m '$OPTARG'" ) ;;
            p)  out+=( 'git push' ) ;;
            *)  return 1 ;;
        esac
    done

    printf '%s\n' "${out[@]}"
}

Se você precisar impor uma ordem da saída (o git push será a última coisa que será emitida se -p for o último na linha de comando com a função acima), então use flags. Isso também não produzirá vários comandos se uma opção for usada várias vezes.

wsgc () {
    local OPTIND=1

    local message
    local do_push=0

    while getopts 'm:p' opt; do
        case "$opt" in
            m)  message="$OPTARG" ;;
            p)  do_push=1 ;;
            *)  return 1 ;;
        esac
    done

    local out=( "git add -A" )

    if [[ -n "$message" ]]; then
        out+=( "git commit -m '$message'" )
    fi

    if (( do_push )); then
        out+=( 'git push' )
    fi

    printf '%s\n' "${out[@]}"
}

Esse último bit da função pode ser encurtado para

local out=( "git add -A" )

[[ -n "$message" ]] && out+=( "git commit -m '$message'" )
(( do_push ))       && out+=( 'git push' )

printf '%s\n' "${out[@]}"
    
por 01.09.2017 / 08:58