# Присваиваем переменной значение:
QT_QPA_PLATFORMTHEME=qt6ct
# проверяем:
echo QT_QPA_PLATFORMTHEME
# qt6ct
Отлично. Всё работает.
То же самое можно сделать так:
# Присваиваем переменной значение:
env QT_QPA_PLATFORMTHEME=qt6ct
# проверяем:
echo QT_QPA_PLATFORMTHEME
# qt6ct
Тоже всё работает. В bash команда env создаёт shell-переменную. В других шеллах эта команда может вести себя по-другому. Например, создавать environment-переменную. Но в bash два вышеприведённых примера эквивалентны.
Но если мы сейчас попробуем запустить Qt6-приложение (пусть это будет feather) в том же терминале таким вот образом:
featherpad
то обнаружим, что приложение не видит эту переменную.
Чтобы передать значение переменной программе, нужно сделать это в той же строке, где мы это приложение запускаем:
# либо так:
QT_QPA_PLATFORMTHEME=qt6ct featherpad
# либо так:
env QT_QPA_PLATFORMTHEME=qt6ct featherpad
Вот сейчас featherpad увидит переменную QT_QPA_PLATFORM и применит Qt-стиль, который указан в qt6ct.
Environment (окружение процесса) – это набор пар ИМЯ=ЗНАЧЕНИЕ, который передаётся каждому запущенному процессу при старте.
Посмотреть значения environment-переменных можно так:
# Посмотреть все переменные:
env
# Посмотреть значение конкретной переменной:
printenv XDG_SESSION_TYPE
# присваиваем значение переменной:
QT_QPA_PLATFORMTHEME=qt6ct
# выводим его:
echo $QT_QPA_PLATFORMTHEME
# qt6ct
printenv QT_QPA_PLATFORMTHEME
# ничего не вывелось
То есть тут мы присвоили значение переменной внутри нашего shell. Но shell-переменная ≠ environment-переменная. Поэтому если мы запустим featherpad без явной передачи переменной, то featherpad эту переменную не увидит.
Если мы хотим создать именно environment-переменную, то это делается так:
export QT_QPA_PLATFORMTHEME=qt6ct
# теперь мы можем проверить её:
printenv QT_QPA_PLATFORMTHEME
# qt6ct
# и теперь можно запустить featherpad:
featherpad
# стиль применился
Если я впишу в ~/.profile:
export QT_QPA_PLATFORMTHEME=qt6ct
... то переменная не попадёт в environment. Потому что я запускаю sway из shell'а и sway наследует environment текущего shell.
# Проверим, логин ли у меня shell:
shopt -q login_shell && echo LOGIN || echo NOT_LOGIN
# NOT_LOGIN
# поэтому .profile не работает
При логине bash читает ~/.bash_profile. Я могу выполнить скрипт ~/.profile внутри ~/.bash_profile:
# ~/.profile
export QT_QPA_PLATFORMTHEME=qt6ct
# ~/.bash_profile
source ~/.profile
Можно конечно объявить environment-переменную прямо в ~/.bash_profile, но ~/.profile + source – считается классическим UNIX-подходом.
Если у меня не работают /etc/profile и ~/.profile, откуда тогда PATH? Ответ:
В современной Linux-системе environment – это продукт PAM + systemd, а shell – просто потребитель.
PAM подгружает модули из /etc/pam.d/login и /etc/pam.d/system-login.
# /etc/pam.d/system-login
# ...
session optional pam_env.so
session required pam_systemd.so
# ...
А сами значения приходят отсюда:
# /etc/login.defs
# ...
ENV_PATH PATH=/usr/local/sbin:/usr/local/bin:/usr/bin
ENV_SUPATH PATH=/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/sbin:/usr/bin
# ...
Это и есть базовый PATH.
PAM – Pluggable Authentication Modules (Подключаемые модули аутентификации). Это слой между программой и системой, который решает: кто ты, можно ли тебя пустить и с какими условиями. Без PAM каждая программа должна была бы сама проверять пароль, настроивать сессию, задавать переменные. А с PAM всё это вынесено в единый механизм.
Как выглядит PAM на практике. Каждая программа имеет файл в /etc/pam.d/. Внутри – цепочка модулей.
login-shell – это shell, запущенный с флагом --login. Только login-shell читает .profile.
Вариант 2. Рекомендуемый для Wayland (лучший): Использовать systemd user environment (я его советовал не случайно).
mkdir -p ~/.config/environment.d
nano ~/.config/environment.d/99-qt.conf
# ~/.config/environment.d/99-qt.conf
QT_QPA_PLATFORMTHEME=qt6ct
Но у меня этот способ не работает. Насколько я понял, у меня нет полноценной "systemd-user session". У меня сессия: TTY -> login -> bash (не login-shell) -> sway.
Проверить видит ли systemd переменную:
# Проверим systemd-user:
systemctl --user show-environment
# Можно проверить так:
systemctl --user show-environment
1. Включить linger, чтобы user systemd жил независимо от логина:
loginctl enable-linger $USER
2. Перезагрузиться и заново войти в TTY
3. Проверить:
systemctl --user show-environment
Должны появиться переменные из ~/.config/environment.d/