Трудно быть багом
Тыдыжь! Может, башнем? Обязательно башнем. И не раз. Весь прод в труху.
Сегодня трём за экспорты.
Имеется задача: нужно создать переменную в bash и затем отменить её экспорт. НО чтобы переменная не сбросилась. Она должна быть доступна в текущей оболочке, но не подпроцессам.
Вроде все очевидно, а нихуя! Погнали в лабораторию.
1. BASHDAYS="hello bashdays"
2. export BASHDAYS
3. _BASHDAYS=$BASHDAYS
4. unset BASHDAYS
5. BASHDAYS=$_BASHDAYS
Пример выше, демонстрирует как это делают ВСЕ! Ну хуита прям полная. Никогда не делай такую блевотню.
Чо происходит:
- Задали переменную (не доступна в подпроцессах)
- Экспортировали (доступна в подпроцессах)
- Скопировали переменную в другую (не доступна в подпроцессах)
- Ансетнули первую переменную (не доступна нигде)
- Задаем переменную (не доступна в подпроцессах)
А можно красивее? Конечно, для этого существует typeset.
Давай перепишем код:
1. BASHDAYS="hello bashdays"
2. export BASHDAYS
3. typeset +x BASHDAYS
- Задаем переменную (не доступна в подпроцессах)
- Экспортировали (доступна в подпроцессах)
- Удаляем атрибут экспорта (не доступна в подпроцессах)
Красиво? Да охуенно! Избавились от говнища и добились желаемого.
Что значит доступна в подпроцессах?
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, привычка наверное.
Давай краба, изучай!








Комментарии