Трудно быть багом

Тыдыжь! Может, башнем? Обязательно башнем. И не раз. Весь прод в труху.

Сегодня трём за экспорты.

Имеется задача: нужно создать переменную в bash и затем отменить её экспорт. НО чтобы переменная не сбросилась. Она должна быть доступна в текущей оболочке, но не подпроцессам.

Вроде все очевидно, а нихуя! Погнали в лабораторию.

1. BASHDAYS="hello bashdays"
2. export BASHDAYS
3. _BASHDAYS=$BASHDAYS
4. unset BASHDAYS
5. BASHDAYS=$_BASHDAYS

Пример выше, демонстрирует как это делают ВСЕ! Ну хуита прям полная. Никогда не делай такую блевотню.

Чо происходит:

  1. Задали переменную (не доступна в подпроцессах)
  2. Экспортировали (доступна в подпроцессах)
  3. Скопировали переменную в другую (не доступна в подпроцессах)
  4. Ансетнули первую переменную (не доступна нигде)
  5. Задаем переменную (не доступна в подпроцессах)

А можно красивее? Конечно, для этого существует typeset.

Роман Шубин
Роман Шубин
CEO & CTO, Главред в «Цифровой улей»
Задать вопрос
Мне иногда кажется, что на любой самописный велосипед, найдется нативная утилита, которую можно найти в коробке.

Давай перепишем код:

1. BASHDAYS="hello bashdays"
2. export BASHDAYS
3. typeset +x BASHDAYS
  1. Задаем переменную (не доступна в подпроцессах)
  2. Экспортировали (доступна в подпроцессах)
  3. Удаляем атрибут экспорта (не доступна в подпроцессах)

Красиво? Да охуенно! Избавились от говнища и добились желаемого.

Что значит доступна в подпроцессах?

1. BASHDAYS="hello bashdays"
2. export BASHDAYS
3. bash
4. echo $BASHDAYS
5. hello bashdays
6. exit
7. typeset +x BASHDAYS
8. bash
9. echo $BASHDAYS
10. хуй с маслом

В пятой строчке вывелось значение переменной, после запускаем bash внутри bash (подпроцесс), выводим переменную, а она пустая. Хотя если сделать exit, то переменная выводится.

Если совсем грубо — родительский процесс выводит переменную, дочерний нет. То есть export на глобальном уровне задает переменную, которая доступна в любых подпроцессах (дочерних).

Всё это справедливо для оболочки Bash, во всяких zsh и т.п. поведение может быть другое.

Есть альтернативы typeset

declare +x BASHDAYS
export -n BASHDAYS

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

Typeset это альтернативный синтаксис для declare предоставленный для совместимости с другими оболочками. Я предпочитаю использовать именно typeset, привычка наверное.

Давай краба, изучай!