Autor Tópico: getopt dentro de funções - bug??? (Resolvido)  (Lida 2900 vezes)

Offline gwarah

  • Usuário Ubuntu
  • *
  • Mensagens: 77
    • Ver perfil
getopt dentro de funções - bug??? (Resolvido)
« Online: 07 de Agosto de 2013, 12:33 »
Olá amigos experts em scripts bash, isso tá me parecendo um bug do interpretador. Criei uma função para gerar nomes de arquivos temporários que utiliza getopts. Esta função foi feita para gerar nomes de arquivos temporários da seguinte forma:

__tmp[_label]_Date<YYYYMMDD_HHMMSS>

Onde [label] aparece no nome se for informado como parâmetro da função. O problema é que na segunda chamada da função informando label, este não é reconhecido. Aparentemente o getopts não está processando uma segunda chamada com a mesma chave. O script com resultado vai abaixo (falha a partir da 3. chamada da função).

-------------------------------
Código: [Selecionar]
#!/bin/bash
# getopt com bug ??

####
#
# Função     : fn_file_tmp
# Objetivo   : Gera um nome para arquivo temporario
# Sintaxe :
#   fn_file_tmp [-l "label"]
#   -l, opcional. Label que vai fazer parte do nome para identificação
#
# Retorno :
#       $?=0, se a geração teve sucesso
#       $FNV_RETORNO= preenchida com o nome do arquivo temporário, caso $?=0
# Observações:
#       Padrão de nomeclatura: __tmp[_label]_Date<YYYYMMDD_HHMMSS>
#
####
function fn_file_tmp() {

    # inicializando variaveis
    opt_found=0
    FN_LABEL=""
    opt_file_tmp=""
    SINTAX="fn_file_tmp [-l \"label\"]"
    
    while getopts "l:" opt_file_tmp
    do
      (( opt_found++ ))
      case $opt_file_tmp in
        l)
            # mensagem de entrada de dados
            FN_LABEL="${OPTARG}"
            if [ -z "${FN_LABEL}" ]; then
                echo "label deve ser informado"
                echo "Sintaxe: ${SINTAX}"
                return 1
            fi
        ;;
        :)
            echo "Opcao -$OPTARG requer argumento."
            echo "Sintaxe: ${SINTAX}"
            return 1
        ;;
        \?)
            echo "Opção inválida: -$OPTARG"
            echo "Sintaxe: ${SINTAX}"
            return 1
        ;;
      esac
    done

    if [ $opt_found -gt 1 ]; then
        echo "Erro. Sintaxe: ${SINTAX}"
        return 1
    fi
    
    # geral o nome do arquivo temporario
    FNV_RETORNO="__tmp"
    [ -n "${FN_LABEL}" ] && FNV_RETORNO=`echo "${FNV_RETORNO}_${FN_LABEL}"`
    FNV_RETORNO="${FNV_RETORNO}_"$(date +"%Y%m%d_%H%M%S")
}

FNV_RETORNO=""

# chamada da função sem parâmetros (ok)
# Resultado 1 __tmp_20130807_122108
fn_file_tmp
echo Resultado 1 $FNV_RETORNO

# chamada da função com -l err (ok)
# Resultado 2 __tmp_err_20130807_122108
fn_file_tmp -l err
echo Resultado 2 $FNV_RETORNO

# chamada da função com -l ttp (falha - nome gerado não tem ttp)
# Resultado 3 __tmp_20130807_122108
fn_file_tmp -l ttp
echo Resultado 3 $FNV_RETORNO

# chamada da função com -l err (falha - nome gerado não tem err)
# Resultado 4 __tmp_20130807_122108
fn_file_tmp -l err
echo Resultado 4 $FNV_RETORNO


Quem puder me ajudar agradeço!

 ;)
« Última modificação: 07 de Agosto de 2013, 15:46 por gwarah »
"Cantar a beleza de ser um eterno aprendiz" (Gonzaguinha)

Offline gwarah

  • Usuário Ubuntu
  • *
  • Mensagens: 77
    • Ver perfil
Re: getopt dentro de funções - bug???
« Resposta #1 Online: 07 de Agosto de 2013, 14:08 »
Não é bug não. Mas eu não descobriria se não consultasse uns especialistas.

http://stackoverflow.com/questions/10454501/why-getopts-within-a-function-fails-to-work

A bronca é resolvida acrescentando local OPTIND=1  antes do getopts

o código agora fica assim:

Código: [Selecionar]
#!/bin/bash
# getopt com bug ??

####
#
# Função     : fn_file_tmp
# Objetivo   : Gera um nome para arquivo temporario
# Sintaxe :
#   fn_file_tmp [-l "label"]
#   -l, opcional. Label que vai fazer parte do nome para identificação
#
# Retorno :
#       $?=0, se a geração teve sucesso
#       $FNV_RETORNO= preenchida com o nome do arquivo temporário, caso $?=0
# Observações:
#       Padrão de nomeclatura: __tmp[_label]_Date<YYYYMMDD_HHMMSS>
#
####
function fn_file_tmp() {

    # inicializando variaveis
   
    opt_found=0
    FN_LABEL=""
    opt_file_tmp=""
    SINTAX="fn_file_tmp [-l \"label\"]"

    local OPTIND=1
    while getopts "l:" opt_file_tmp
    do
      (( opt_found++ ))
      case $opt_file_tmp in
        l)
            # mensagem de entrada de dados
            FN_LABEL="${OPTARG}"
            if [ -z "${FN_LABEL}" ]; then
                echo "label deve ser informado"
                echo "Sintaxe: ${SINTAX}"
                return 1
            fi
        ;;
        :)
            echo "Opcao -$OPTARG requer argumento."
            echo "Sintaxe: ${SINTAX}"
            return 1
        ;;
        \?)
            echo "Opção inválida: -$OPTARG"
            echo "Sintaxe: ${SINTAX}"
            return 1
        ;;
      esac
    done

    if [ $opt_found -gt 1 ]; then
        echo "Erro. Sintaxe: ${SINTAX}"
        return 1
    fi
   
    # geral o nome do arquivo temporario
    FNV_RETORNO="__tmp"
    [ -n "${FN_LABEL}" ] && FNV_RETORNO=`echo "${FNV_RETORNO}_${FN_LABEL}"`
    FNV_RETORNO="${FNV_RETORNO}_"$(date +"%Y%m%d_%H%M%S")
}

FNV_RETORNO=""

# chamada da função sem parâmetros (ok)
# Resultado 1 __tmp_20130807_122108
fn_file_tmp
echo Resultado 1 $FNV_RETORNO

# chamada da função com -l err (ok)
# Resultado 2 __tmp_err_20130807_122108
fn_file_tmp -l err
echo Resultado 2 $FNV_RETORNO

# chamada da função com -l ttp (Ok - Nome com label ttp)
# Resultado 3 __tmp_ttp_20130807_140734
fn_file_tmp -l ttp
echo Resultado 3 $FNV_RETORNO

# chamada da função com -l err (Ok - Nome com label err)
# Resultado 4 __tmp_err_20130807_140734
fn_file_tmp -l err
echo Resultado 4 $FNV_RETORNO

"Cantar a beleza de ser um eterno aprendiz" (Gonzaguinha)