Как я устанавливаю переменную среды на командной строке и имею ее, появляются в командах?

При проверке с помощью ping-запросов известного хоста его именем (например. ping www.google.com) возвраты ping: unknown host но проверяя с помощью ping-запросов IP (например. ping 8.8.8.8) хорошо работает затем, у Вас есть проблема разрешения DNS - пытаются добавить эти записи в /etc/resolv.conf:

nameserver 8.8.8.8
nameserver 8.8.4.4
167
24.11.2012, 01:35
5 ответов

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

TEST=foo; echo $TEST

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

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

TEST=foo your-application
196
27.01.2020, 19:28
  • 1
    Что относительно/usr/bin/env? это не работает также, Вы знаете почему? –  Benubird 09.07.2014, 19:43
  • 2
    Та же причина - оболочка расширяется $TEST прежде чем командная строка выполняется. Однажды echo работает (также отмечают это echo будет обычно переводить в оболочку встроенную команду а не в /bin/echo) это видит переменный набор в своей среде. Однако echo $TEST не говорит echo производить содержание переменной TEST от его среды. Это говорит оболочке работать echo причем аргумент - то независимо от того, что в настоящее время находится в названной переменной TEST - и это - две совсем других вещи. –  peterph 09.07.2014, 20:41
  • 3
    @peterph, Если оболочка разворачивает переменную в командной строке, прежде чем это на самом деле выполнит команду затем, почему это не разворачивает его в var=value sh -c 'echo "$var"'? –  haccks 12.03.2018, 23:56
  • 4
    Поскольку я объяснил Вам здесь: это - потому что переменные расширены в двойных кавычках (например, "… $var …") но не в одинарных кавычках (например, '… $var …').   С тех пор echo "$var" внутренние одинарные кавычки, что вся строка передается новому (sh -c) оболочка, не будучи интерпретированным внешней, интерактивной оболочкой.   …   (Cont’d) –  G-Man Says 'Reinstate Monica' 14.03.2018, 22:21
  • 5
    (Cont’d) …  , Поскольку igal вчера сказал, существует два раунда парсинга — хотя я полагаю, что igal неправильно читают Ваш вопрос.   нет двух раундов парсинга кроме парсинга, который сделан родительской оболочкой.   существует два раунда парсинга — один сделанный внешней, интерактивной (родительской) оболочкой,   и один новым (sh -c) дочерняя оболочка. положительная сторона –  G-Man Says 'Reinstate Monica' 14.03.2018, 22:21

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

В

var=value echo whatever

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

Если Вы записали

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

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

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

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

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

(...) выше запусков подоболочка (новый процесс оболочки в большинстве оболочек), таким образом, любая переменная объявила, там будет только влиять на ту подоболочку, таким образом, я ожидал бы, что код выше произведет "1: оцените" и "2": или "2: whatever-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"

С ударом и zsh (но не пепел, 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 оболочки удаляют свою особенность (здесь, что присвоения переменных в от них остаются в силе после того, как они возвратились)),


¹ разговор Stricktly, это не абсолютно верно. Несколько реализаций будут заботиться о переменных среды локализации (LANG, LOCPATH, LC_*...), реализация GNU заботится о POSIXLY_CORRECT переменная среды (выдерживают сравнение env echo --version с POSIXLY_CORRECT=1 env echo --version в системе GNU).

43
27.01.2020, 19:28
  • 1
    В моих целях это - правильное решение. Я не хочу, чтобы переменный 'var' загрязнил среду, как это делает в принятом ответе. –  kronenpj 13.09.2017, 18:12

Можно получить эту работу при помощи:

TEST=foo && echo $TEST
5
27.01.2020, 19:28
  • 1
    В этом случае, TEST=foo работает как отдельный оператор - он только установлен в контексте echo. –  codeforester 03.01.2017, 21:54

Вы делаете это правильно, но синтаксис bash легко неправильно истолковать :вы можете подумать, что echo $TESTзаставляет echoизвлекать TESTenv var, а затем печатать его, но это не так. Так дано

export TEST=123

, затем

TEST=456 echo $TEST

включает следующую последовательность:

  1. Оболочка анализирует всю командную строку и выполняет все подстановки переменных, поэтому командная строка становится

    TEST=456 echo 123
    
  2. Он создает временные переменные, установленные перед командой, поэтому сохраняет текущее значение TESTи перезаписывает его на 456; командная строка теперь

    echo 123
    
  3. Он выполняет оставшуюся команду, которая в данном случае выводит 123 на стандартный вывод (, поэтому оставшаяся команда оболочки даже не использовала временное значениеTEST)

  4. Восстанавливает значениеTEST

Вместо этого используйте printenv, так как он не требует подстановки переменных:

>> 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
>>
21
27.01.2020, 19:28

Как вы уже обнаружили, в Bash TEST=456 echo $TESTработает не так, как вы ожидали, потому что вы обращаетесь к переменной в той же строке, которая в данный момент интерпретируется оболочкой. Но будьте уверены, переменная установлена ​​на время действия текущей команды. Чтобы убедиться в этом, вы можете сделать что-то вроде этого:

show () { echo "${!1}" ;}
TEST=456 show TEST
0
05.03.2021, 03:34

Теги

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