Retorna erro no shellscript ao invés de sair no erro

5

Eu sei que set -e é meu amigo para sair com erro. Mas o que fazer se o script for originado, por ex. uma função é executada a partir do console? Eu não quero fechar o console em erro, eu só quero parar o script e exibir a mensagem de erro.

Preciso verificar o $? de cada comando à mão para tornar isso possível?

Aqui está um exemplo de script myScript.sh para mostrar o problema:

#!/bin/sh
set -e

copySomeStuff()
{
    source="$1"
    dest="$2"
    cp -rt "$source" "$dest"
    return 0
}

installStuff()
{
    dest="$1"
    copySomeStuff dir1 "$dest"
    copySomeStuff dir2 "$dest"
    copySomeStuff nonExistingDirectory "$dest"
}

O script é usado assim:

$ source myScript.sh
$ installStuff

Isso apenas fechará o console. O erro exibido por cp é perdido.

    
por Alex 29.07.2016 / 11:21

2 respostas

5

Eu recomendaria ter um script que você executa como um sub-shell, possivelmente sourcing um arquivo para ler nas definições de função. Deixe esse script definir a opção errexit shell para si mesmo.

Quando você usa source na linha de comando, "o script" é efetivamente seu shell interativo. A saída significa encerrar a sessão do shell. Existem possivelmente maneiras de contornar isso, mas a melhor opção, se você quiser definir errexit para uma sessão, seria simplesmente ter:

#!/bin/bash

set -o errexit

source file_with_functions
do_things_using_functions

Benefício adicional: não poluirá a sessão interativa com funções.

    
por 29.07.2016 / 11:52
2

Se você fonte que irá ignorar o #! e irá aplicar set -e para o shell de chamada, assim será aplicada a todos os comandos subseqüentes.

você pode forçar um sub-shell:

copySomeStuff()
{
    (
        set -e
        source="$1"
        dest="$2"
        cp -r "$source" "$dest"
        return 0
    )
}

Também por segurança:

  • Não use o nome da variável em maiúsculas, que provavelmente colidirá com nomes de ambiente. (nós tivemos uma pergunta na semana passada sobre por que um script não funcionou, ele tinha uma variável PATH)

  • Use aspas.

  • Sempre use a opção -t ou -T para cp , mv , ln . por exemplo.

    • cp -t destination_directory source_files …
    • cp -T source_file destination_file

    observe que -t e -T são extensões do Gnu e não estão disponíveis em outros Unixes, portanto, para portabilidade, você pode substituir o -t :

    • cp source_files … destination_directory/

    Eu não sei de um formulário seguro alternativo para -T

por 29.07.2016 / 12:37