Яке значення "_ ="?


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ця змінна знову не включатиме. Що відбувається?


Відповіді:


16

Коли ви виконуєте set -a var=99, трапляються три чіткі речі (пов'язані з вашим запитанням):

  1. Набір параметрів ( -a) (зворотне виконання set +a) для експорту vars.
  2. Позиційні параметри "встановлюються" у відповідності з параметрами ( $1встановлено на var=99).
  3. Підкреслення змінної оболонки $_встановлено на останній параметр (розгорнутий).

набір -а

Виконання 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щоб уникнути інтерпретації опції (і набору є багато) зі значеннями, які починаються з тире ( -).

Встановлює список аргументів (перелік позиційних параметрів), що знаходиться після --. Це справедливо у всіх розумних оболонках (не в csh et al). Позиційні аргументи друкуються з "$ @" (або подібним "$ *", не рівним).

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

_ = останній аргумент

І значення змінної внутрішньої оболонки _змінюються на останній аргумент виконаного рядка. Це НЕ вірно майже у всіх оболонках (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

Підкреслення - це спеціальна змінна оболонки. Що ви бачите тут - це _змінна підкреслення ( ) зі значенням 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 et al).
Стрілка

1
@Arrow Хоча відповідно до останнього рядка відповіді Боба Еджера, це призведе до того, що всі змінні згодом будуть встановлені / змінені експортованими, що може бути не тим, що ви хочете.
TripeHound

8

І зауважу echo $var, нічого не дасть. … Що трапилось?

У не надто тонкому відбитку bash (1) ми знаходимо

set[ --abefhkmnptuvxBCEHPT] [ назва опції ] [ арг …]   [ ] [ назва опції ] [ арг-o
set+abefhkmnptuvxBCEHPT+o ...]

            ︙
    Коли параметри вказані, вони встановлюють або скасовують атрибути оболонки. Будь-які аргументи , що залишилися після обробки опцій розглядаються в якості значень позиційних параметрів і присвоюються в порядку, щоб $1, $2... .$n

Це означає, set -a var=99що не встановлює змінну середовища varна 99; це встановлює $1на var=99. Спробуйте echo "$1"або echo "$*"і побачите.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.