Что означает «_ =»?

29

После запуска set -a var=99я могу найти предложение в выводе set:

...
TERM=xterm
UID=0
USER=root
VIRTUAL_ENV_DISABLE_PROMPT=1
_=var=99
colors=/etc/DIR_COLORS
...

Кто-нибудь может сказать мне, что означает "_ ="?

Отмечу, что echo $varничего не даст. Если я запускаю set -a, то setэта переменная больше не будет включаться. Что происходит?

yode
источник

Ответы:

16

Когда вы выполняете set -a var=99, происходят три разные вещи (связанные с вашим вопросом):

  1. Задать опцию ( -a) (обратное действие set +a) для экспорта переменных.
  2. Позиционные параметры «устанавливаются» на следующие параметры ( $1устанавливаются на var=99).
  3. Подчеркивание переменной оболочки $_устанавливается на последний параметр (расширенный).

установить -a

Выполнение set -aпомечает все последующие (новые или измененные) переменные как экспортированные (во всех оболочках, кроме cshи некоторых связанных оболочек).

$ set -a
$ myvariable=wer
$ env | grep myvariable
myvariable=wer

Для того, чтобы оправиться от этого параметра, просто изменить -к +:

$ set +a
$ unset myvariable              # to erase it from the environment if it
                                # was exported before the change of set +a
$ myvariable=456544654          # A new value of the variable.
$ env | grep "variable"         # No output means the var does not exist
                                # in the current environment

установить var = 99

Что должно быть set -- var=99на самом деле, чтобы избежать интерпретации опции (и set имеет много) со значениями, которые начинаются с тире ( -).

Устанавливает список аргументов (список позиционных параметров) равным после --. Это действительно во всех разумных оболочках (не в csh et al). Позиционные аргументы печатаются с помощью «$ @» (или аналогичного «$ *», не равного).

$ set -- a=1 b=2 c=3
$ echo "$@"
a=1 b=2 c=3

_ = Last_argument

И значение внутренней переменной оболочки _изменяется на последний аргумент выполненной строки. Это НЕ верно почти для всех оболочек (jsh, ash, yash, dash, lksh, mksh, ksh93, attsh и, конечно, csh и tcsh), за исключением bash.

$ echo one two last argument
one two last argument

$ echo "$_"
argument

$ echo This is a new: last_argument
This is a new: last_argument

$ echo "$_"
last_argument

Обратите внимание, что значение в $_это значение после расширения:

$ a="A New_Argument"
$ echo Something else to test: "$a"
Something else to test: A New_Argument

$ echo "$_"
A New_Argument

Вот почему, когда вы выполняете:

$ set -a myvar=99; set | grep 'myvar'
_=myvar=99

Вы получите описание переменной оболочки '$ _'. Это также работает:

$  set -a myvar=99; declare -p _
declare -- _="myvar=99"
Стрела
источник
37

Подчеркивание на самом деле является специальной переменной оболочки. Здесь вы видите _переменную underscore ( ) со значением var=99. Он доступен только для чтения и поддерживается оболочкой. Это:

  • Устанавливается при запуске оболочки, содержит абсолютное имя файла оболочки или сценария, который выполняется, как передано в списке аргументов.
  • После этого он расширяется до последнего аргумента предыдущей команды после расширения.
  • При проверке почты этот параметр содержит имя почтового файла.
  • Также устанавливается полный путь к каждой выполненной команде и помещается в среду, экспортированную в эту команду.

Ваш пример попадает во вторую категорию. Вы ввели:

set -a var=99  

Так последний аргумент был var=99, и это было значение вы настраивали (вы не настраивали varк 99). Следовательно, _был настроен на это. И вот что сообщается:

_=var=99  

Это немного сбивает с толку, но первое =указывает на присвоение переменной _, а второе является частью значения.

Также стоит упомянуть, что эта -aопция setприведет к экспорту всех определенных впоследствии переменных .

Боб Айгер
источник
16

Правильный ответ будет зависеть от используемой вами оболочки:

  • ибо bashвсе, что сказал @BobEager, применимо
  • для zshнего задается только последний аргумент предыдущей команды и полный путь к команде в среде команды
  • некоторые оболочки вроде dashтолько устанавливают эту переменную при запуске интерактивного сеанса

Могут быть и другие особенности в других оболочках. Как таковой, $_он не определен в POSIX, поэтому следует учитывать потенциальные проблемы переносимости при его использовании.

Примечание: если вы намерены присвоить значение 99 varи сделать его доступным в среде последующих подпроцессов, правильный синтаксис для достижения этого:

export var=99
Дмитрий Григорьев
источник
2
Также правильный синтаксис unset var;set -a; var=99. Работает во всех резонирующих оболочках (не csh и др.).
Стрелка
1
@Arrow Хотя в соответствии с последней строкой ответа Боба Эйгера это приведет к тому, что все переменные, впоследствии установленные / измененные, будут экспортированы, что может не соответствовать вашим ожиданиям.
TripeHound
8

И я к сведению echo $varничего не дам. … Что случилось?

В не очень мелкий шрифт Баш (1) , мы находим

set[ --abefhkmnptuvxBCEHPT] [ имя-опции ] [ аргумент …]   [ ] [ имя-опции ] [ аргумент …]-o
set+abefhkmnptuvxBCEHPT+o

            Options
    При указании параметров они устанавливают или отменяют атрибуты оболочки. Любые аргументы , оставшиеся после обработки опций рассматриваются в качестве значений позиционных параметров и присваиваются в порядке, чтобы $1, $2... .$n

Это означает, set -a var=99что не устанавливает переменную окружения varв 99; это устанавливает $1к var=99. Попробуйте echo "$1"или, echo "$*"и вы увидите.

Скотт
источник