Как использовать переменную из одной функции в другой в скрипте на Bash?

«Как использовать переменную из одной функции в другой в скрипте на Bash?» — вопрос из категории Скриптинг и автоматизация, который задают на 23% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В Bash-скриптах для передачи данных между функциями я использую несколько подходов в зависимости от задачи:

  1. Через возвращаемое значение (exit code и stdout): Функции в Bash не возвращают значения в привычном смысле, но можно "вернуть" данные, выведя их в stdout, а статус — через return.

    get_hostname() {
        # Функция 'возвращает' значение, выводя его
        echo "server-prod-01"
    }
    
    deploy() {
        # Захватываю вывод функции в переменную
        local target_host
        target_host=$(get_hostname)
        echo "Деплой на хост: $target_host"
        # Далее используем $target_host для ssh или scp
    }
    
    deploy
  2. Через глобальные переменные (с осторожностью): Изменение переменной в функции делает её видимой глобально, если не объявлена local.

    config_file=""
    
    find_config() {
        # Изменяю глобальную переменную
        config_file="/etc/app/config.yaml"
    }
    
    parse_config() {
        # Использую глобальную переменную
        if [[ -f "$config_file" ]]; then
            echo "Чтение конфига: $config_file"
        fi
    }
    
    find_config
    parse_config
  3. Через передачу аргументов по ссылке (используя nameref в Bash 4.3+): Позволяет функции изменять переменную, переданную из вызывающего кода.

    #!/bin/bash
    
    set_config_value() {
        local -n ref=$1 # 'ref' становится ссылкой на переменную, имя которой передано
        ref="new_value"
    }
    
    my_var="old_value"
    echo "До: $my_var"          # До: old_value
    set_config_value my_var     # Передаю ИМЯ переменной
    echo "После: $my_var"       # После: new_value

Моя рекомендация для скриптов автоматизации:

  • Использовать первый подход (вывод в stdout) для передачи данных. Он самый чистый и предсказуемый.
  • Объявлять все переменные внутри функций как local, чтобы избежать нежелательных побочных эффектов.
  • Для сложных структур данных использовать JSON и инструменты типа jq для их обработки и передачи между функциями.