2010-09-08 2 views
35

Я использую скрипт, который распространяется с использованием функции источника bash;Как вы возвращаетесь к исходному сценарию bash?

#!/bin/bash 

source someneatscriptthatendsprematurely.sh 

Я хочу, чтобы иметь возможность вернуться из этого сценария, не нарушая основного сценария.

Использование выходных прерываний основного скрипта, возврат действителен только в функциях, и эксперимент с $ (выход 1) тоже не работает.

Итак, можно ли вернуться в скрипт sub-bash без нарушения основного bash?

Любая помощь оценена!

+0

Ответа на этот вопрос paxdiablo is perfect and should accepted. – Tino

ответ

52

Вам нужно return заявления:

return [n]

Вызывает функцию для выхода с возвращаемым значением указанного n. Если n опущено, статус возврата - это номер последней команды, выполняемой в теле функции. Если используется вне функции, но во время выполнения скрипта командой . (source), это заставляет оболочку прекратить выполнение этого сценария и вернуть либо n, либо статус выхода последней команды, выполняемой в скрипте, в качестве статуса выхода из сценарий. Если используется вне функции, а не во время выполнения скрипта на ., статус возврата является ложным. Любая команда, связанная с ловушкой RETURN, выполняется до того, как выполнение возобновится после функции или скрипта.

Вы можете увидеть это в действии со следующими двумя сценариями:

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

При запуске script1.sh, вы видите:

hello 
hello again 
+4

Обратите внимание, что вы должны «возвращать 0» явно по умолчанию, если можете. Не делать этого может привести к нежелательному поведению в родительском скрипте. т.е. '[-z" non-existant-file "] && return' фактически вернет 1. –

+1

@BrettRyan проблема с вашим примером заключается в том, что' [-z "несуществующий-файл"] && return 0' вернет 1 Так что говорить людям явно «возвращать 0», а затем показывать пример, где это не работает, является сбивающим с толку. – Segfault

+0

Бретт, на самом деле это не имеет значения в примере, который я опубликовал, поскольку вызывающий скрипт фактически не проверяет возвращаемое значение каким-либо образом (через, например, 'if',' $? 'Или' set -e') , В любом случае, я вполне уверен, что приведенная мной цитата делает поведение понятным в этом случае. – paxdiablo

1

ли это важно, что вы можете изменить переменные окружения? Так как в противном случае вы можете просто выполнить сценарий, выполнив его без источника:

someneatscriptthatendsprematurely.sh 
0

У меня была такая же проблема, только сейчас

я понял, что добавление функции клетчатой ​​и возвращения не будет также возвращать функцию на ее например, вызывающего абонента.

На 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 

Что здесь происходит, поскольку шашки является единственным местом, возвращающий так install_packer_linux будет по-прежнему продолжают

Таким образом, вы можете сделать две вещи здесь.Либо сохранить текущий формат (функция вызова другой функции), как и оценить с помощью truthy значение затем вернуться, если значения не truthy или переписать проверки на основной функции installer_packer_linux

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 
} 

Заметьте, что мы добавлено || вернуть после проверок и объединить проверки, используя & & , так что если обе проверки не являются правдивыми, мы возвращаем функцию

Смежные вопросы