Вопрос или проблема
У нас возникла проблема при попытке установить локальную переменную в функции с использованием 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
ожидают имя переменной, а не её значение.
Вот что необходимо скорректировать для правильной работы скрипта:
- Вместо передачи значения переменной
myparam
как второго аргумента функции, нужно передать её имя непосредственно без символа доллара. - Чтобы изменения, внесенные через ссылочную переменную, отразились на оригинальной переменной, необходимо изменить ссылочную переменную внутри функции.
Исправленный код будет выглядеть следующим образом:
#!/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 и избегать распространенных ошибок, связанных с их объявлением и использованием.