Время от времени я собираю сценарий bash, и мне кажется, что есть несколько способов установки переменной:
key=value
env key=value
export key=value
Когда вы находитесь внутри скрипта или отдельной команды (например, я часто связываю переменную с помощью средства запуска Wine для установки правильного префикса Wine), они кажутся полностью взаимозаменяемыми, но, конечно, это не может иметь место.
В чем разница между этими тремя методами, и можете ли вы привести пример, когда я бы хотел использовать каждый из них?
Определенно связано с тем, В чем разница между `VAR = ...` и `export VAR = ...`? но я хочу знать, как env
вписывается в это тоже, и некоторые примеры, показывающие преимущества каждого из них тоже было бы неплохо :)
command-line
bash
Оли
источник
источник
export key=value
это расширенный синтаксис и не должен использоваться в переносимых сценариях (то есть#! /bin/sh
).Ответы:
Давайте рассмотрим конкретный пример. Команда
grep
использует переменную среды, вызываемуюGREP_OPTIONS
для установки параметров по умолчанию.В настоящее время. Учитывая, что файл
test.txt
содержит следующие строки:выполнение команды
grep one test.txt
вернетЕсли вы запустите grep с
-v
параметром, он вернет несовпадающие строки, поэтому вывод будетТеперь мы попытаемся установить параметр с переменной среды.
Переменные среды, установленные без
export
, не будут наследоваться в среде команд, которые вы вызываете.Результат:
Очевидно, что вариант
-v
не был переданgrep
.Вы хотите использовать эту форму, когда вы устанавливаете переменную только для оболочки, например,
for i in * ; do
если вы не хотите экспортировать$i
.Тем не менее, переменная передается в среду этой конкретной командной строки, так что вы можете сделать
который вернет ожидаемое
Вы используете эту форму для временного изменения среды данного конкретного экземпляра запущенной программы.
Экспорт переменной приводит к наследованию переменной:
возвращается сейчас
Это наиболее распространенный способ установки переменных для использования впоследствии запущенных процессов в оболочке.
Все это было сделано в Bash.
export
это встроенный bash;VAR=whatever
это синтаксис bashenv
с другой стороны, это программа сама по себе. Когдаenv
вызывается, происходят следующие вещи:env
выполняется как новый процессenv
модифицирует окружающую среду иenv
Процесс заменяетсяcommand
процессом.Пример:
Эта команда запустит два новых процесса: (i) env и (ii) grep (фактически, второй процесс заменит первый). С точки зрения
grep
процесса, результат в точности совпадает сОднако вы можете использовать эту идиому, если вы находитесь за пределами bash или не хотите запускать другую оболочку (например, когда вы используете
exec()
семейство функций, а неsystem()
вызов).Дополнительная заметка о
#!/usr/bin/env
Это также, почему идиома
#!/usr/bin/env interpreter
используется, а не#!/usr/bin/interpreter
.env
не требует полного пути к программе, потому что она используетexecvp()
функцию, которая ищетPATH
переменную, как это делает оболочка, а затем заменяет себя командой run. Таким образом, его можно использовать, чтобы узнать, где интерпретатор (например, perl или python) «сидит» на пути.Это также означает, что, изменяя текущий путь, вы можете влиять на то, какой вариант Python будет вызываться. Это делает возможным следующее:
вместо запуска Caliber, приведет к
источник
env
? Я имею в виду, когда вы открываете новую оболочку, у вас всегда есть несколько переменных. Так что какая-то программа должна была ихexport
редактировать, верно?set var=blah
?