Obtém resultado específico da função

3

Existe uma maneira de retornar um valor específico em uma função de eco?

return me permite retornar um status de saída para a função. Eu preciso retornar uma estrutura de dados mais sofisticada, como uma matriz ou uma seqüência de caracteres. Normalmente eu precisaria ecoar o valor que eu quero ser retornado. Mas e se eu precisar ecoar mensagens informativas na minha função, e eu só precisar obter o último eco que contém o resultado de que preciso?

Eu tenho este pedaço de código que eu gostaria de fazer uma função, mas eu gostaria de manter o eco informativo como eles são úteis para guiar a entrada do usuário.

modules=(module1 module2 module3)
is_valid=-1
while [ $is_valid -lt 1 ] 
do
    echo "Please chose and order the available modules you need:"
    echo -e $(list_array_choices modules[@])
    echo -n "> "
    read usr_input
    choices=("$usr_input")
    is_valid=$(is_list_in_range choices[@] ${#modules[@]})
    [ "$is_valid" -eq -1 ] && echo -e "Error: your input is invalid.\n"
done

Eu gostaria de fazer algo como

function get_usr_choices() {
    modules=${!1}
    is_valid=-1
    while [ $is_valid -lt 1 ] 
    do
        echo "Please chose and order the available modules you need:"
        echo -e $(list_array_choices modules[@])
        echo -n "> "
        read usr_input
        choices=("$usr_input")
        is_valid=$(is_list_in_range choices[@] ${#modules[@]})
        [ "$is_valid" -eq -1 ] && echo -e "Error: your input is invalid.\n"
    done
    echo ${choices[@]}  # This is the result I need.
}
choices=$(get_usr_choices modules[@])

Ai, os ecos estragam completamente a saída quando eu obtenho uma string contendo todo o eco, incluindo os informativos. Existe uma maneira de fazer o que eu quero de uma maneira limpa?

    
por kaligne 27.04.2016 / 10:48

2 respostas

3

Você pode enviar todos os outros conteúdos diretamente para a tela, supondo que você não queira fazer nada além da exibição.

Algo similar a isso poderia ser feito

#!/bin/bash

function get_usr_choices() {
        #put everything you only want sending to screen in this block
        {
                echo these
                echo will
                echo go
                echo to
                echo screen
        }> /dev/tty
        #Everything after the block is sent to stdout which will be picked up by the assignment below
        echo result
}
choices=$(get_usr_choices)

echo "<choices is $choices>"

Rodando isso retorna

these
will
go
to
screen
<choices is result>
    
por 27.04.2016 / 11:04
2

As variáveis não são locais no bash por padrão, então você pode fazer:

function get_usr_choices() {
    modules=${!1}
    is_valid=-1
    while [ $is_valid -lt 1 ] 
    do
        echo "Please chose and order the available modules you need:"
        echo -e $(list_array_choices modules[@])
        echo -n "> "
        read usr_input
        choices=("$usr_input")
        is_valid=$(is_list_in_range choices[@] ${#modules[@]})
        [ "$is_valid" -eq -1 ] && echo -e "Error: your input is invalid.\n"
    done
}

get_usr_choices
# use choices here

A única pegadinha é não chamar get_usr_choices em uma subshell usando $(...) ou um pipe, senão você perderá choices .

    
por 27.04.2016 / 10:58