Де "Export var = value" недоступний?


31

Я підхопив - ймовірно, на Usenet в середині 1990-х (!) - цю конструкцію

export var=value

- це башизм, і це переносний вираз

var=value
export var

Я виступаю за це протягом багатьох років, але останнім часом хтось кинув мені виклик з цього приводу, і я дійсно не можу знайти жодної документації, яка б підкріплювала те, що раніше було моїм твердим переконанням.

Google "export: command not found", схоже, не викликає випадків, коли хтось насправді мав цю проблему, тож навіть якщо це справді, я думаю, це не дуже часто.

(Удари , які я отримую , здається, новачки , які копіювати / вставити знаки пунктуації, і в кінцевому підсумку з 'export: command not foundабо кілька таких, або намагаються використовувати exportз sudo, і новачком csh. Користувачів намагаються використовувати синтаксис Bourne оболонки)

Я, безумовно, можу сказати, що він працює як на OS X, так і на різних дистрибутивах Linux, включаючи ті, де shє dash.

sh$ export var=value
sh$ echo "$var"
value
sh$ sh -c 'echo "$var"'  # see that it really is exported
value

Чи можна в сучасному світі сказати, що export var=valueце безпечно у використанні?

Я хотів би зрозуміти, які наслідки є. Якщо він не є портативним до v7 "Bourne classic", це навряд чи більше дрібниць. Якщо є виробничі системи, де оболонка дійсно не справляється з цим синтаксисом, це було б корисно знати.


2
дякую, я нарешті зрозумів, чому я так часто бачу те, що мені здалося марним: var = value; export var
Thorsten Staerk

2
Є ще кілька ящиків Solaris, що б’ються навколо, і вони, як відомо, в своїх стандартних інструментах сумлінні; на іншому кінці спектра, чи не busyboxйде власна мінімальна оболонка? (Мені не вдається спробувати жодну секунду.)
Ульріх Шварц

Дякую Ульріху, Соларіс цілком може бути винуватцем того, чому цей довгий синтаксис все ще існує.
Торстен Стаерк

Відповіді:


20
export foo=bar

не підтримувався оболонкою Bourne (старою оболонкою з 70-х років, з якої shпоходять такі сучасні реалізації, як ash / bash / ksh / yash / zsh). Це було введено ksh.

У оболонці Борна ви зробите:

foo=bar export foo

або:

foo=bar; export foo

або з set -k:

export foo foo=bar

Тепер, поведінка:

export foo=bar

варіюється від оболонки до оболонки.

Проблема полягає в тому, що призначення та прості аргументи команд аналізуються та трактуються по-різному.

foo=barВище інтерпретуються деякими оболонки в якості аргументу команди і інших як призначення (іноді).

Наприклад,

a='b c'
export d=$a

трактується як:

'export' 'd=b' 'c'

з деякими оболонками ( ash, більш старими версіями zsh(в емуляції sh) yash), і:

'export' 'd=b c'

в інших ( bash, ksh).

Поки

export \d=$a

або

var=d
export $var=$a

буде трактуватися однаково у всіх оболонках (як 'export' 'd=b' 'c'), оскільки цей зворотний косий знак або знак долара зупиняє ті оболонки, які підтримують його, щоб розглядати ці аргументи як призначення.

Якщо exportце котирується або є результатом якогось розширення (навіть частково), залежно від оболонки, воно також перестане отримувати спеціальне лікування.

Детальніше про це див. У розділі " Чи потрібні лапки для призначення місцевих змінних? ".

Синтаксис Борна, хоча:

d=$a; export d

інтерпретується однаково всі оболонки без неоднозначності ( d=$a export dтакож працював би в оболонці Bourne і оболонках, сумісних з POSIX, але не в останніх версіях, zshякщо не в shемуляції).

Це може вийти набагато гірше. Дивіться, наприклад , недавню дискусію про те,bash коли залучені масиви.

(IMO, помилка введення цієї функції ).


Я був здивований, що крапка з комою не потрібна foo=bar export foo, як я завжди її бачив. Я знаю, що експорт є вбудованим, але чому він foo=bar; foo=baz export foo; echo $fooповодиться інакше, ніж foo=bar; foo=baz /bin/cat /dev/null; echo $foo?
jrw32982 підтримує Моніку

3
@ jrw32982, тому що це вбудований. Ви все ще отримуєте це в сучасних оболонках POSIX, але тільки для спеціальних вбудованих, які exportє.
Стефан Шазелас

Хоча це і обговорює declare, ні export, я рекомендую кожному, хто піклується про безпеку, прочитати дискусію за посиланням, яке StéphaneChazelas надав bash.bugs .
John1024

Чудова відповідь! Але знадобилося багато часу, щоб d=$a export dвсе було розтлумачено однаково всі оболонки без неоднозначності ;-)
conny

@conny, d=$a export dбільше не працює zsh, тому я оновив відповідь. Див. Редагування.
Стефан Шазелас

28

Це не башізм, а синтаксис, сумісний з POSIX. Це насправді почалося як кшизм досить давно і згодом було прийнято майже всі оболонки на основі синтаксису Бурна. Єдиний горезвісний виняток - /bin/shSolaris 10 та старші, який дотримується спадкового синтаксису оболонки Борна. Сподіваємось, Solaris 11 використовує оболонку, сумісну з POSIX /bin/sh.

До речі, exportвже була вбудована команда у спадщину оболонки Борна, так що гугл для export: command not foundбув оманливим.

Ось попередня поведінка оболонки Борна, коли exportвона поєднується з афектом:

$ export var=22
var=22: is not an identifier

Для ностальгіків вихідний код цієї оригінальної оболонки Борна доступний і може бути складений для більшості дистрибутивів Unix та Linux.


Дякую за історичну інформацію та правильне повідомлення про помилку Google! Очевидна в ретроспективі, рум'яна ...
триплета

4
Це не вихідний код оригінальної оболонки Борна, це модифікований OpenSolaris sh. Це оболонка Борна, але після того, як зазнала десятиліття еволюції. Оригінальну оболонку Борна, що постачається з Unix V7, можна знайти у товаристві спадщини Unix
Stéphane Chazelas

1
@ StéphaneChazelas Строго кажучи, ви як завжди правильно. Однак зауважте, що я не написав "оригінальну оболонку Bourne", а "цю оригінальну оболонку Bourne", оскільки я мав на увазі оболонку, використовувану Solaris 10, та її вихідний код, який можна скласти на сучасних платформах. Зауважимо також, що оболонка Bourne мала кілька функцій, доданих між 1977 та 1989 роками, але потім перестала розвиватися (поза перенесенням / адаптацією до новіших платформ та виправлень помилок) протягом останніх 25 років.
jlliagre
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.