Почему бы не экспортировать переменные в той же строке, которую вы им присвоили?


44

От того, что является последним аргументом предыдущей команды?

shellcheck говорит вам не экспортировать переменные в той же строке, в которой вы их присваиваете.

Мне было интересно, почему?

Применим ли тот же совет alias, declare, export, local, readonly, и typeset?




9
Рассматриваемое правило проверки оболочки - SC2155. В вики о shellcheck есть довольно хорошая документация .
phunehehe

3
Также некоторые старые оболочки не будут принимать exportи присваивать вместе. Наследуемый 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


Так что, если кто-то устанавливает переменную из литерала, и нет кода выхода, который нужно отбрасывать, нет ничего плохого в том, чтобы делать все это в одной строке.
Монти Хардер

1
Что касается этой ошибки, то нет. Но поскольку теперь удаленные ответы оказались наполовину правильными между ними, оболочка Bourne не поддерживала синтаксис присваивания export, поэтому в течение нескольких лет поступало мудрое решение сделать это, если интерпретатором, вероятно, будет оболочка Bourne.
JdeBP

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

Это было охвачено моим первым предложением.
JdeBP
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.