Как установить переменную среды в командной строке и отобразить ее в командах?

Если я запустил

export TEST=foo
echo $TEST

Он выводит foo.

Если я запустил

TEST=foo echo $TEST

Это не так. Как я могу получить эту функциональность без использования экспорта или сценария?

110 голосов | спросил ashleysmithgpu 23 52012vEurope/Moscow11bEurope/MoscowFri, 23 Nov 2012 14:17:52 +0400 2012, 14:17:52

4 ответа


130

Это связано с тем, что оболочка расширяет переменную в командной строке до , она фактически запускает команду, и в то время переменная не существует. Если вы используете

TEST=foo; echo $TEST

он будет работать.

export заставит переменную отображаться в среде последующих исполняемых команд (о том, как это работает в bash, см. help). Если вам требуется только, чтобы переменная отображалась в среде одной команды, используйте то, что вы пробовали, т. Е.:

help export
ответил peterph 23 52012vEurope/Moscow11bEurope/MoscowFri, 23 Nov 2012 14:37:20 +0400 2012, 14:37:20
30

Я подозреваю, что вы хотите иметь переменные shell , чтобы иметь ограниченную область действия, а не переменные среды. Переменные среды - это список строк, переданных командам при выполнении .

В

var=value echo whatever

Вы передаете строку var=value в среду, которую получает эхо. Тем не менее, echo ничего не делает с его списком окружения и в любом случае в большинстве оболочек, echo встроен и, следовательно, не выполняется .

Если вы написали

var=value sh -c 'echo "$var"'

Это было бы другим вопросом. Здесь мы передаем var=value в команду sh, а sh - использовать свою среду. Оболочки преобразуют каждую из переменных, которые они получают из своей среды в переменную оболочки, поэтому переменная окружения var sh будет преобразована в $var, и когда он расширяет его в этой командной строке echo, это станет echo value. Поскольку среда по умолчанию унаследована, echo также получит var=value в своей среде (или если она была выполнена), но опять же, echo code> не заботится об окружающей среде.

Теперь, если я подозреваю, что вы хотите ограничить объем переменных оболочки, существует несколько возможных подходов.

Портативно (Bourne и POSIX):

(var=value; echo "1: $var"); echo "2: $var"

В верхней части (...) запускается суб-оболочка (новый процесс оболочки в большинстве оболочек), поэтому любая заявленная там переменная затронет только эту суб-оболочку, поэтому я ожидаю, что вышеприведенный код выведет «1 : value "и" 2: "или" 2: any-var-was-set-to-before ".

С большинством борнеподобных оболочек вы можете использовать функции и локальные встроенные функции:

f() {
  local var
  var=value
  echo "1: $var"
}
f
echo "2: $var"

С помощью zsh вы можете использовать встроенные функции:

(){ local var=value; echo "1: $var"; }; echo "2: $var"

или

function { local var=value; echo "1: $var"; }; echo "2: $var"

С bash и zsh (но не ash, pdksh или AT & T ksh) этот трюк также работает:

var=value eval 'echo "1: $var"'; echo "2: $var"

Вариант, который работает в нескольких оболочках (dash, mksh, yash)), но не zsh (если в эмуляции sh /ksh):

var=value command eval 'echo "1: $var"'; echo "2: $var"

(используя команду command перед специальным встроенным (здесь eval)) в оболочках POSIX устраняет их специальность (здесь переменные назначения из них остаются в силе после того, как они вернулись))

ответил Stéphane Chazelas 23 52012vEurope/Moscow11bEurope/MoscowFri, 23 Nov 2012 15:31:04 +0400 2012, 15:31:04
4

Вы можете получить эту работу, используя:

TEST=foo && echo $TEST
ответил pradeepchhetri 23 52012vEurope/Moscow11bEurope/MoscowFri, 23 Nov 2012 14:23:58 +0400 2012, 14:23:58
0

Вы делаете это правильно, но синтаксис bash легко неверно истолковывает: вы можете подумать, что echo $TEST вызывает echo для извлечения TEST env var, тогда распечатайте его, это не так. Вместо этого оболочка анализирует всю командную строку и выполняет все подстановки переменных; Тогда он создает временные вары (TEST в вашем случае), THEN выполняет команду, которая приходит после, с этими vars в ее env.

Попробуйте следующее:

>> export TEST=123
>> printenv TEST
123
>> TEST=456 printenv TEST
456
>> printenv TEST && TEST=456 printenv TEST && TEST=789 printenv TEST && printenv TEST
123
456
789
123
>>
ответил Oliver 5 AMpThu, 05 Apr 2018 03:13:46 +030013Thursday 2018, 03:13:46

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132