Я читаю « Руководство по Bash для начинающих ». Он говорит:
Если первым символом
PARAMETER
является восклицательный знак, Bash использует значение переменной, образованной из оставшейся части,PARAMETER
как имя переменной; затем эта переменная расширяется, и это значение используется в остальной части подстановки, а не само значениеPARAMETER
. Это известно как непрямое расширение.
Приведенный пример:
franky ~> echo ${!N*}
NNTPPORT NNTPSERVER NPX_PLUGIN_PATH
Я здесь не совсем понимаю:
значение переменной, сформированное из оставшейся части
PARAMETER
Как PARAMETER
справедливо !N*
, то
остальная часть
PARAMETER
просто N*
. Как это могло образовать переменную? Обыскал ли там Bash все возможные команды?
источник
Похоже, что существует исключение, когда данное «косвенное обращение» заканчивается на
*
, как здесь. В этом случае он дает все имена переменных, которые начинаются с указанной вами части (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
источник
${!my*}
расширяется до myA, myB, myA экспортируется с его текущим значением, а myB устанавливается на «пока» и экспортируется. Не очень полезно.Вы столкнулись с исключением при косвенной обработке, где, если последний символ - это
*
все переменные с префиксом, заданным ранее, будут возвращены.источник
*
случая, это то же самое, что и${${VAR}}
?${${VAR}}
записываемый как${$VAR}
, недопустим, поскольку$VAR
возвращает строку, которая не может следовать за$
знаком; чтобы использовать строку в качестве имени переменной, вам нужно ввести один уровень косвенности (как указано в самом исходном вопросе), т.е. вы можете использовать${!VAR}
, что делает именно то, что вы ожидаете (ошибочно, но понятно)${$VAR}
.Вы можете обратиться к этому документу GNU для bash за авторитетной информацией.
https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html#Shell-Parameter-Expansion
Но в основном косвенное расширение не выполняется
${!prefix*}
как одно из исключений, в вашем примере N - это префикс.Документ объяснит, что такое косвенное расширение в bash.
источник