Проблема, переглянута
Чесно кажучи, посібник з цього приводу бентежить. У посібнику GNU Bash сказано:
Середовище для будь-якої простої команди або функції [зауважте, що це виключає вбудовані файли] може тимчасово доповнюватись, додаючи до нього призначення параметрів, як описано в Параметри оболонки. Ці оператори присвоєння впливають лише на оточення, яке бачить ця команда.
Якщо ви дійсно аналізуєте речення, там йдеться про те, що середовище для команди / функції змінено, але не середовище для батьківського процесу. Отже, це буде працювати:
$ TESTVAR=bbb env | fgrep TESTVAR
TESTVAR=bbb
оскільки середовище для команди env було змінено до її виконання. Однак це не спрацює:
$ set -x; TESTVAR=bbb echo aaa $TESTVAR ccc
+ TESTVAR=bbb
+ echo aaa ccc
aaa ccc
через те, коли розширення параметра виконується оболонкою.
Кроки перекладача
Інша частина проблеми полягає в тому, що Баш визначає ці кроки для свого інтерпретатора:
- Зчитує свої вхідні дані з файлу (див. Сценарії оболонки), з рядка, що подається як аргумент до параметра -c виклику (див. Виклик Bash), або з терміналу користувача.
- Розбиває введення на слова та оператори, дотримуючись правил цитування, описаних у цитуванні. Ці лексеми розділені метасимволами. Розширення псевдонімів виконується цим кроком (див. Псевдоніми).
- Розбирає маркери на прості та складені команди (див. Команди оболонки).
- Виконує різні розширення оболонки (див. Розширення оболонки), розбиваючи розгорнуті маркери на списки імен файлів (див. Розширення імен файлів) та команд та аргументів.
- Виконує всі необхідні переспрямування (див. Перенаправлення) та видаляє оператори переспрямування та їх операнди зі списку аргументів.
- Виконує команду (див. Виконання команд).
- За бажанням чекає завершення команди та збирає статус її виходу (див. Стан виходу).
Тут відбувається те, що вбудовані не отримують власного середовища виконання, тому вони ніколи не бачать модифікованого середовища. Крім того, прості команди (наприклад , / bin / відлуння) дійсно отримати модифіковану ennvironment (тому приклад окр працював) , але розширення оболонки відбувається в поточній середовищі на етапі # 4.
Іншими словами, ви не передаєте 'aaa $ TESTVAR ccc' в / bin / echo; ви передаєте інтерпольований рядок (розширений у поточному середовищі) до / bin / echo. У цьому випадку, оскільки в поточному середовищі немає TESTVAR , ви просто передаєте команду 'aaa ccc'.
Резюме
Документація може бути набагато чіткішою. Добре, що є переповнення стека!
Дивіться також
http://www.gnu.org/software/bash/manual/bashref.html#Command-Execution-Environment