Что такое косвенная экспансия? Что значит ${!ВАР*} означает?


Я читаю "Bash руководство для начинающих". Он говорит:

если первый символ PARAMETER является восклицательным знаком, Bash использует значение переменной, образованной из остальной части PARAMETER в имя переменной, эта переменная затем расширяется и это значение используется в остальной части замещения, а не значение . Это называется косвенным расширением.

пример, приведенный это:

franky ~> echo ${!N*}
NNTPPORT NNTPSERVER NPX_PLUGIN_PATH

Я не совсем понимаю вот:

значение переменной, образованной из остальной части PARAMETER

как PARAMETER это просто !N*, потом

остальное PARAMETER

это просто N*. Как это может сформировать переменную? Неужели Баш искал там все возможные команды?

4 53

4 ответа:

если вы читали bash man page, это в основном подтверждает то, что вы сказали:

если первый символ параметра-восклицательный знак (!), вводится уровень переменной косвенности. Bash использует значение переменной, сформированной из остальной части параметра, в качестве имени переменной; эта переменная затем расширяется, и это значение используется в остальной части подстановки, а не значение самого параметра. Это называется косвенным расширение.

однако, читая дальше:

исключения из этого являются расширения ${!prefix*} и ${!name[@]} описано ниже.

${!prefix*} имена, соответствующие префикс. Расширяется до имен переменных, имена которых начинаются с префикса, разделенного первым символом IFS специальная переменная.

другими словами, ваш конкретный пример ${!N*} это исключение to правило, которое вы процитировали. Это тут, однако, работают так, как рекламируется в ожидаемых случаях, таких как:

$ export xyzzy=plugh ; export plugh=cave

$ echo ${xyzzy}  # normal, xyzzy to plugh
plugh

$ echo ${!xyzzy} # indirection, xyzzy to plugh to cave
cave

кажется, есть исключение, когда данная "косвенность" заканчивается на *, как и здесь. В этом случае он дает все имена переменных, которые начинаются с указанной вами части (N здесь). Bash может это сделать, потому что он отслеживает переменные и знает, какие из них существуют.

истинная косвенность заключается в следующем:
Скажем, у меня есть переменная $VARIABLE значение 42, и у меня есть еще одна переменная $NAME значение VARIABLE. ${!NAME} даст мне 42. Вы используете значение единицы переменная, чтобы сказать вам имя другого:

$ NAME="VARIABLE"
$ VARIABLE=42
$ echo ${!NAME}
42

Да, он ищет все возможные расширения переменных после !. Если бы вы сделали:

echo ${!NP*}

вы получите только NPX_PLUGIN_PATH.

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

:~> export myVar="hi"
:~> echo ${!my*}
    myVar
:~> export ${!my*}="bye"
:~> echo $myVar
    bye

вы попали в исключение в косвенной обработке, где, если последний символ *, будут возвращены все переменные, которые имеют префикс, заданный ранее.