Чому б не експортувати змінні в той самий рядок, який ви їм призначили?


44

З Який останній аргумент попередньої команди?

shellcheck повідомляє вам не експортувати змінні в той самий рядок, який ви їм призначили.

Мені було цікаво, чому?

Застосуємо чи той же рада alias, declare, export, local, readonly, і typeset?




9
Розглянутий правило оболонки SC2155. На вікі- шелчекі є досить хороша документація .
phunehehe

3
Також деякі старі снаряди не приймають exportі не призначають їх разом. Наприклад, Sheirloom Bourne Shell видає помилку "foo = 2 не ідентифікатор".
Денніс Вільямсон

Відповіді:


54

Проблема в тому , що в Bash кожна команда має тільки один код виходу. Коли ви export foo="$(false)"вихідний код falseпросто викидаєте. Якщо ви замість цього зробите

foo="$(false)"
export foo

невдала перша команда може діяти, наприклад, шляхом errexitвстановлення.

Оголошення та призначення рядкового букваря, такого як export foo='bar', звичайно, не страждає від цієї проблеми. Але зміни є єдиною постійною умовою в розробці програмного забезпечення, і це просто добре ведення таких завдань, які підтверджують майбутнє, розділяючи їх.

На додаток до конкретних команд для призначення, які ви згадуєте, в одному призначенні також є кілька команд, таких як foo="$(false)$(true)". Див pipefailв man bashпротягом ще однієї такої пастки.

Ще слід пам’ятати, що послідовність декларування та призначення іноді є актуальною. Наприклад, вам потрібно буде оголосити змінні перед їх призначенням. (На жаль, неможливо оголосити змінні перед тим, як призначити їх вперше.)local readonly


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

1
Що стосується цієї помилки оболонки, ні. Але оскільки видалені зараз відповіді отримали напівправильно між ними, оболонка Борна не підтримувала синтаксис присвоєння export, тому протягом декількох років надходило мудрість щодо цього, якщо чийсь перекладач, ймовірно, був оболонкою Борна.
JdeBP

@JdeBP, зауважте, що оболонка Bourne підтримувала foo=$(cmd) export foo, хоча з тим самим застереженням, що cmdстатус виходу втрачається (але він викликав вихід оболонки, якщо не вдалося set -e).
Стефан Шазелас

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