Продолжение к фоновой части в этом вопросе .
В bash
я могу использовать ${!FOO}
для двойной замены, в zsh
${(P)FOO}
. В обоих случаях работает старая школа (hack-y) eval \$$FOO
.
Итак, самая разумная и логичная вещь для меня - ${${FOO}}, ${${${FOO}}}…
двойная / тройная / n замена. Почему это не работает, как ожидалось?
Второе: что делает \
в eval
заявлении? Я считаю, что это спасение, что-то вроде eval \$$$FOO
невозможного. Как сделать тройную / n замену тем, что работает в каждой оболочке?
bash
zsh
variable-substitution
Profpatsch
источник
источник
l3=l2; eval eval eval echo \\\$\\$\$$l3
→53294
так что не совсем модульный.eval $(eval echo \$$l2)
? Я ненавижу Баш, это не имеет абсолютно никакого смысла.источник
Предположим, что значение
FOO
является допустимым именем переменной (скажемBAR
),eval \$$FOO
разбивает значениеBAR
на отдельные слова, обрабатывает каждое слово как шаблон подстановочного знака и выполняет первое слово результата как команду, передавая другие слова в качестве аргументов. Обратная косая черта перед долларом делает его трактуемым буквально, поэтому аргумент, передаваемыйeval
встроенному, представляет собой строку из четырех символов$BAR
.${${FOO}}
это синтаксическая ошибка Он не выполняет «двойную замену», потому что такой функции нет ни в одной из общих оболочек (в любом случае, с этим синтаксисом). В zsh${${FOO}}
он действителен и представляет собой двойную подстановку, но он ведет себя не так, как вам бы хотелось: он выполняет два последовательных преобразования значенияFOO
, оба из которых являются преобразованием идентификаторов, так что это просто причудливый способ записи${FOO}
.Если вы хотите трактовать значение переменной как переменную, будьте осторожны с правильным заключением в кавычки. Намного проще, если вы установите результат в переменную:
источник
{ba,z}sh
решениеВот функция, которая работает в обоих
{ba,z}sh
. Я верю, что это также POSIX-совместимый.Не сходя с ума от цитирования, вы можете использовать его для многих уровней косвенности следующим образом:
Или, если у вас есть больше (!?!) Уровней косвенности, вы можете использовать цикл.
Предупреждает когда дано:
источник
Так же , как
${$foo}
не работает на месте${(P)foo}
вzsh
, ни делает${${$foo}}
. Вам просто нужно указать каждый уровень косвенности:Конечно,
${!${!foo}}
не работаетbash
, потомуbash
что не допускает вложенные замены.источник
zsh
что устанавливается гораздо чаще, чем вы можете предположить. Возможно, он не связан с тем,sh
какbash
часто (но не всегда), но он все еще может быть доступен для сценариев оболочки. Думайте об этом как о Perl или Python.Зачем вам это нужно?
Вы всегда можете сделать это в несколько шагов, таких как:
Или используйте функцию вроде:
Затем:
FWIW, в
zsh
:источник
Решение POSIX
Не сходя с ума от цитирования, вы можете использовать эту функцию для многих уровней косвенности следующим образом:
Или, если у вас есть больше (!?!) Уровней косвенности, вы можете использовать цикл.
Предупреждает когда дано:
источник