2010-09-08 6 views
35

Uso uno script che si estende utilizzando la funzione di origine bash;Come si torna a uno script bash di origine?

#!/bin/bash 

source someneatscriptthatendsprematurely.sh 

Mi piacerebbe poter tornare da quella sceneggiatura, senza rompere la sceneggiatura principale.

Utilizzare le interruzioni di uscita dello script principale, il ritorno è valido solo nelle funzioni e la sperimentazione con $ (exit 1) non sembra funzionare.

Quindi, è possibile tornare in uno script sub-bash senza interrompere la bash principale?

Qualsiasi aiuto apprezzato!

+0

La risposta di paxdiablo è perfetta e dovrebbe essere accettata. – Tino

risposta

52

avete bisogno dell'espressione return:

return [n]

Provoca una funzione per uscire con il valore di ritorno specificato da n. Se n viene omesso, lo stato di ritorno è quello dell'ultimo comando eseguito nel corpo della funzione. Se utilizzato al di fuori di una funzione, ma durante l'esecuzione di uno script tramite il comando . (origine), la shell interrompe l'esecuzione di tale script e restituisce n o lo stato di uscita dell'ultimo comando eseguito all'interno dello script come stato di uscita di il copione. Se utilizzato all'esterno di una funzione e non durante l'esecuzione di uno script da ., lo stato di ritorno è falso. Qualsiasi comando associato alla trappola RETURN viene eseguito prima che l'elaborazione riprenda dopo la funzione o lo script.

È possibile vedere in azione con i seguenti due script:

script1.sh: 
    . script2.sh 
    echo hello again 
script2.sh: 
    echo hello 
    return 
    echo goodbye 

Quando si esegue script1.sh, si vede:

hello 
hello again 
+4

Nota che dovresti 'restituire 0' in modo esplicito per impostazione predefinita se puoi. Non farlo potrebbe causare un comportamento indesiderato nello script genitore. cioè '[-z" file inesistente "] && return' restituirà effettivamente 1. –

+1

@BrettRyan il problema con il tuo esempio è che' [-z "file non esistente"] && return 0' restituirà 1 Quindi dire alle persone di "restituire 0" esplicitamente e quindi mostrare un esempio in cui ciò non funziona è confuso. – Segfault

+0

Brett, che in realtà non ha importanza nell'esempio che ho postato poiché lo script chiamante non controlla effettivamente il valore restituito in alcun modo (tramite, ad esempio, 'if',' $? 'O' set -e') . In ogni caso, sono abbastanza sicuro che la citazione che ho incluso rende chiaro il comportamento in quel caso. – paxdiablo

1

E 'importante che si può cambiare le variabili di ambiente? Dal momento che altrimenti si può semplicemente eseguire lo script eseguendo senza fonte:

someneatscriptthatendsprematurely.sh 
0

Ho avuto lo stesso problema solo ora

mi sono reso conto che l'aggiunta di una funzione di controllo e di ritorno che non tornerà anche la funzione sul proprio chiamante per esempio.

Su bash_functions

function install_packer_linux() { 
    check_wget && check_unzip 
    wget https://releases.hashicorp.com/packer/1.1.2/packer_1.1.2_linux_amd64.zip 
    unzip packer_1.1.2_linux_amd64.zip 
    mv packer ~/.local/bin 
    rm -f packer_1.1.2_linux_amd64.zip 
} 


function check_unzip() { 
    if ! [ -x "$(command -v unzip)" ]; then 
    echo "Error: unzip is not installed" 
    return 1 
    else 
    return 0 
    fi 
} 

function check_wget() { 
    if ! [ -x "$(command -v wget)" ]; then 
    echo "Error!: wget is not installed" 
    return 1 
    else 
    return 0 
    fi 
} 


$ source ~/.bash_functions 

Quello che succede qui è fin dagli ispettori è l'unico posto la sua restituito in modo install_packer_linux sarà ancora continuerà

modo da poter fare due cose qui.O mantenere il formato corrente (funzione di chiamata un'altra funzione), come è e valutare utilizzando il valore truthy poi tornare se i valori non sono truthy o riscrivere il controllo sulla funzione installer_packer_linux principale

Truthy:

function install_packer_linux() { 
    check_wget && check_unzip || return 
    wget https://releases.hashicorp.com/packer/1.1.2/packer_1.1.2_linux_amd64.zip 
    unzip packer_1.1.2_linux_amd64.zip 
    mv packer ~/.local/bin 
    rm -f packer_1.1.2_linux_amd64.zip 
} 

Avviso siamo aggiunto || restituire dopo gli assegni e concatenare gli assegni utilizzando & quindi se non entrambi i controlli sono veritieri restituiamo la funzione