Como devolver o código de saída? Erro: return: Leitura: argumento numérico requerido

7

Aqui está uma versão simplificada do meu script. Minha pergunta é: como faço para retornar o código de saída de apt-get neste caso?

#!/bin/bash
install_auto() {
apt-get -h > /dev/null 2>&1
if [ $? -eq 0 ] ; then
    return $(sudo apt-get install --assume-yes $@)
fi
return 1
}
echo "installing $@"
install_auto "$@"
echo $?
echo "finished"
exit 0

A saída é:

./install_test.sh: line 5: return: Reading: numeric argument required

Atualização: criei algo que funciona:

return $(sudo apt-get install --assume-yes "$@" >/dev/null 2>&1; echo $?)

Essa é uma boa abordagem?

    
por MountainX 07.07.2013 / 20:26

2 respostas

7

O return() do Bash só pode retornar argumentos numéricos. Em qualquer caso, por padrão, ele retornará o status de saída da última execução do comando. Então, tudo que você realmente precisa é:

#!/usr/bin/env bash
install_auto() {
apt-get -h > /dev/null 2>&1
if [ $? -eq 0 ] ; then
    sudo apt-get install --assume-yes $@
fi
}

Você não precisa definir explicitamente um valor a ser retornado, pois, por padrão, uma função retornará $? . No entanto, isso não funcionará se o primeiro comando apt falhar e você não entrar no loop if . Para torná-lo mais robusto, use isto:

#!/usr/bin/env bash
install_auto() {
apt-get -h > /dev/null 2>&1
ret=$?
if [ $ret -eq 0 ] ; then
    ## If this is executed, the else is ignored and $? will be
    ## returned. Here, $?will be the exit status of this command
    sudo apt-get install --assume-yes $@
else
    ## Else, return the exit value of the first apt-get
    return $ret
fi
}

A regra geral é que, para que uma função retorne o status de saída de um trabalho específico e não necessariamente o último que foi executado, você precisará salvar o status de saída em uma variável e retornar a variável:

function foo() {
    run_a_command arg1 arg2 argN
    ## Save the command's exit status into a variable
    return_value= $?

    [the rest of the function  goes here]
    ## return the variable
    return $return_value
}

EDIT: Na verdade, como @gniourf_gniourf apontado nos comentários, você poderia simplificar bastante a coisa toda usando && :

install_auto() {
  apt-get -h > /dev/null 2>&1 &&
  sudo apt-get install --assume-yes $@
}

O valor de retorno desta função será um dos seguintes:

  1. Se apt-get -h falhar, ele retornará seu código de saída
  2. Se apt-get -h for bem-sucedido, ele retornará o código de saída de sudo apt-get install .
por 07.07.2013 / 20:54
1

Para completar, aqui está minha função real com algumas modificações, como sugerido por @terdon e @gniourf_gniourf:

install_auto() {
    if [ ! $# -gt 0 ] ; then
        echo "usage: $0 package_name [package_name ...]"
    fi 

    apt-get -h > /dev/null 2>&1
    if [ $? -eq 0 ] ; then
        if [ -f "$@" ] || [[ "$@" =~ '/' ]] ; then
            sudo gdebi -n "$@"
            return $?
        else    
            sudo apt-get install --assume-yes "$@"
            return $?
        fi
    fi

    zypper help > /dev/null 2>&1
    if [ $? -eq 0 ] ; then
            sudo zypper --non-interactive --no-gpg-checks --quiet install --auto-agree-with-licenses "$@"
            return $?
    fi

    #may check other package managers in the future

    echo "ERROR: package manager not found"
    return 255
}

Agradeço quaisquer sugestões adicionais.

    
por 07.07.2013 / 21:34