Давайте рассмотрим конкретный пример. Команда grep
использует переменную среды, вызываемую GREP_OPTIONS
для установки параметров по умолчанию.
В настоящее время. Учитывая, что файл test.txt
содержит следующие строки:
line one
line two
выполнение команды grep one test.txt
вернет
line one
Если вы запустите grep с -v
параметром, он вернет несовпадающие строки, поэтому вывод будет
line two
Теперь мы попытаемся установить параметр с переменной среды.
Переменные среды, установленные без export
, не будут наследоваться в среде команд, которые вы вызываете.
GREP_OPTIONS='-v'
grep one test.txt
Результат:
line one
Очевидно, что вариант -v
не был передан grep
.
Вы хотите использовать эту форму, когда вы устанавливаете переменную только для оболочки, например, for i in * ; do
если вы не хотите экспортировать $i
.
Тем не менее, переменная передается в среду этой конкретной командной строки, так что вы можете сделать
GREP_OPTIONS='-v' grep one test.txt
который вернет ожидаемое
line two
Вы используете эту форму для временного изменения среды данного конкретного экземпляра запущенной программы.
Экспорт переменной приводит к наследованию переменной:
export GREP_OPTIONS='-v'
grep one test.txt
возвращается сейчас
line two
Это наиболее распространенный способ установки переменных для использования впоследствии запущенных процессов в оболочке.
Все это было сделано в Bash. export
это встроенный bash; VAR=whatever
это синтаксис bash env
с другой стороны, это программа сама по себе. Когда env
вызывается, происходят следующие вещи:
- Команда
env
выполняется как новый процесс
env
модифицирует окружающую среду и
- вызывает команду, указанную в качестве аргумента.
env
Процесс заменяется command
процессом.
Пример:
env GREP_OPTIONS='-v' grep one test.txt
Эта команда запустит два новых процесса: (i) env и (ii) grep (фактически, второй процесс заменит первый). С точки зрения grep
процесса, результат в точности совпадает с
GREP_OPTIONS='-v' grep one test.txt
Однако вы можете использовать эту идиому, если вы находитесь за пределами bash или не хотите запускать другую оболочку (например, когда вы используете exec()
семейство функций, а не system()
вызов).
Дополнительная заметка о #!/usr/bin/env
Это также, почему идиома #!/usr/bin/env interpreter
используется, а не #!/usr/bin/interpreter
. env
не требует полного пути к программе, потому что она использует execvp()
функцию, которая ищет PATH
переменную, как это делает оболочка, а затем заменяет себя командой run. Таким образом, его можно использовать, чтобы узнать, где интерпретатор (например, perl или python) «сидит» на пути.
Это также означает, что, изменяя текущий путь, вы можете влиять на то, какой вариант Python будет вызываться. Это делает возможным следующее:
echo -e '#!/usr/bin/bash\n\necho I am an evil interpreter!' > python
chmod a+x ./python
export PATH=.
calibre
вместо запуска Caliber, приведет к
I am an evil interpreter!
export key=value
это расширенный синтаксис и не должен использоваться в переносимых сценариях (то есть#! /bin/sh
).