Объявление локальной ссылки имени в Bash не работает.

Вопрос или проблема

У нас возникла проблема при попытке установить локальную переменную в функции с использованием nameref.

Код скрипта следующий:

#!/usr/bin/bash
msg=hello
myparam=''

superfunc () {
productfile=$1
local -n refmyparam=$2
}

superfunc $msg $myparam
echo $myparam

При выполнении этого кода мы получаем ошибку:

 строка 7: local: `': недействительный идентификатор

Мы используем GNU bash, версия 5.2.21

local -n и declare -n требуют имени переменной в качестве их значения, а не ее значения.

Кроме того, создание локальной ссылочной переменной не изменяет оригинальную переменную. Вам нужно изменить ссылочную переменную, чтобы увидеть, как изменение отражается на оригинале:

#!/bin/bash
msg=hello
myparam=''

superfunc () {
    productfile=$1
    local -n refmyparam=$2
    refmyparam=changed     # Измените локальную переменную.
}

superfunc $msg myparam     # Без знака доллара для $2!
echo $myparam              # Изменено!

.

Ответ или решение

Когда вы пытаетесь использовать ссылочные переменные (nameref) в bash, важно понимать, как именно они работают и как корректно их объявлять. В вашем случае возникла ошибка в скрипте, поскольку попытка передать значение переменной вместо имени переменной приводит к неправильной интерпретации.

Давайте проанализируем ваш код.

#!/usr/bin/bash
msg=hello
myparam=''

superfunc () {
    productfile=$1
    local -n refmyparam=$2
}

superfunc $msg $myparam
echo $myparam

Ошибка, с которой вы столкнулись (line 7: local: '': not a valid identifier), указывает на то, что вы передаете значение переменной myparam в качестве аргумента в функцию superfunc. Однако конструкции local -n и declare -n ожидают имя переменной, а не её значение.

Вот что необходимо скорректировать для правильной работы скрипта:

  1. Вместо передачи значения переменной myparam как второго аргумента функции, нужно передать её имя непосредственно без символа доллара.
  2. Чтобы изменения, внесенные через ссылочную переменную, отразились на оригинальной переменной, необходимо изменить ссылочную переменную внутри функции.

Исправленный код будет выглядеть следующим образом:

#!/bin/bash
msg=hello
myparam=''

superfunc () {
    productfile=$1
    local -n refmyparam=$2  # Здесь $2 будет 'myparam', а не его значение
    refmyparam=changed      # Изменяем значение через ссылку
}

superfunc $msg myparam     # No dollar sign for $2!
echo $myparam              # Теперь 'myparam' изменен на 'changed'

В этом измененном варианте myparam передается без знака доллара, и local -n refmyparam=$2 правильно ссылается на переменную myparam. При изменении refmyparam, это изменение также отразится на myparam.

Важно учитывать:

  • Использование local -n создает локальную ссылку на переменную. Это означает, что любые изменения в refmyparam будут касаться переменной myparam в контексте родительской функции, что позволяет вам управлять переменными более гибко.
  • Названия переменных не могут начинаться с цифр и не могут содержать специальные символы (кроме символа подчеркивания). Это важно для того, чтобы избежать ошибок при объявлении переменных.

Зная это, вы сможете эффективно использовать ссылочные переменные в ваших скриптах bash и избегать распространенных ошибок, связанных с их объявлением и использованием.

Оцените материал
Добавить комментарий

Капча загружается...