Який найкращий distro / shell-agnostic спосіб встановлення змінних середовища?


31

Питання каже все це. В даний час я використовую Arch Linux і zsh, але я хотів би, щоб рішення, яке (як мінімум) працює як на VT, так і в xterms, а також (сподіваємось, бажано) продовжувати працювати, якщо я переключаю distros або shell.

Я чув дико розрізнені відповіді на це питання в різних документах дистрибутива. Ubuntu говорить "використовувати .pam_environment". Я думаю, що в Arch, те, що вони рекомендують, залежить від вашої оболонки. В даний час я все вкладаю в .profile, і якщо оболонка не є джерелом, що з якихось причин (наприклад, bash, якщо існує. Але, схоже, має бути кращий шлях.


2
Це не має нічого спільного з distro і все, що стосується оболонки. Не впевнений, що існує портативний спосіб зробити це.
Джозеф Р.

Хм. Дивовижно .
strugee

Відповіді:


29

На жаль, не існує повністю портативного місця для встановлення змінних середовища. Два файли, які найближче наближаються ~/.profile, це традиційне місце розташування і працює нестандартно для багатьох установок, а ~/.pam_environmentтакож сучасна, звичайна, але обмежена альтернатива.

Що вкласти ~/.pam_environment

Файл ~/.pam_environmentчитається всіма методами входу, які використовують PAM та ввімкнено цей файл. Сьогодні це стосується більшості систем Linux.

Основною перевагою ~/.pam_environmentє те, що (при включенні) воно зчитується до запуску оболонки користувача, тому воно працює незалежно від типу сеансу, оболонки входу та інших складностей. Він навіть працює для неінтерактивних входів, таких як su -c somecommandі ssh somecommand.

Основне обмеження ~/.pam_environmentполягає в тому, що ви можете розміщувати там просто прості завдання, а не складний синтаксис оболонки. Синтаксис цього файлу такий.

  • Файли аналізуються по рядках.
  • Провідна пробіл ігнорується.
  • Ви можете необов'язково починати рядки з exportта пробілу (не вкладка, перехідна фігура).
  • Після цього кожен рядок повинен мати форму, VAR=VALUEде VAR складається з літер, цифр та підкреслень.
  • # починає коментар, він не може відображатися у значенні.
  • Якщо VALUE починається з 'або "містить іншу ідентичну цитату, то VAR встановлюється на рядок між цитатами (все після другої лапки ігнорується). В іншому випадку VAR встановлюється на рядок після =знаку.
  • Якщо немає =, змінна видаляється з оточення.

Тож, перевернувшись, ~/.pam_environmentпрацює у великій кількості обставин. З іншого боку, ви не можете мати жодних динамічних налаштувань, таких як базувати значення змінної на іншій змінній (наприклад, додавання каталогу в PATH) або використовувати висновок команди (наприклад, перевірити наявність каталогу чи програми) та деякі символів ( #'", новий рядок) неможливо або клопітно ввести значення.

Що вкласти ~/.profile

Цей файл повинен мати синтаксис портативного (POSIX) sh. Використовуйте розширення ksh або bash (масиви [[ … ]]тощо), лише якщо ви знаєте, що ваша система має такі оболонки як /bin/sh.

Цей файл може читатися сценаріями в автоматизованих програмах, тому він не повинен викликати програми, які виробляють який-небудь вихід або виклик exec. Якщо ви хочете зробити це для входу в текстовий режим, робіть це лише для інтерактивних оболонок. Приклад:

case $- in *i*)
  # Display a message if I have new mail
  if mail -e; then echo 'You have new mail'; fi
  # If zsh is available, and this looks like a text-mode login, run zsh
  case "`ps $PPID` " in
    *" login "*)
      if type zsh >/dev/null 2>/dev/null; then exec zsh; fi;;
  esac
esac

Це приклад використання /bin/shв якості оболонки для входу та переходу до улюбленої оболонки. Дивіться також, як я можу використовувати bash як оболонку входу, коли мій sysadmin відмовляється дозволити мені змінити його

Коли ~/.profileне читається неграфічний логін?

Різні оболонки для входу читають різні файли.

Якщо ваша оболонка для входу є невдалою

Bash читає ~/.bash_loginабо ~/.bash_profileякщо вони існують замість ~/.profile. Також bash не читає ~/.bashrcв оболонці входу, навіть якщо він інтерактивний. Щоб більше ніколи не запам'ятовувати ці примхи, створіть ~/.bash_profileнаступні два рядки:

. ~/.profile
case $- in *i*) . ~/.bashrc;; esac

Дивіться також Які файли налаштування слід використовувати для налаштування змінних середовища з bash?

Якщо оболонка для входу - zsh

Зш читає ~/.zprofileі ~/.zlogin, але ні ~/.profile. Zsh має інший синтаксис від sh, але може читати ~/.profileв режимі емуляції sh. Ви можете використовувати це для своїх ~/.zprofile:

emulate sh -c '. ~/.profile'

Дивіться також Zsh не потрапляє ~ / .profile

Якщо ваша оболонка для входу - це якась інша оболонка

Зробити там не так багато, окрім використання /bin/shв якості оболонки для входу, а улюблена оболонка (наприклад, риба) лише як інтерактивна оболонка. Ось що я роблю з zsh. Дивіться вище для прикладу виклику іншої оболонки з ~/.profile.

Віддалені команди

Якщо викликати віддалену команду, не проходячи інтерактивну оболонку, не всі оболонки читають файл запуску.

Ksh зчитує файл, вказаний ENVзмінною, якщо вам вдасться передати його.

Bash зчитує, ~/.bashrcякщо він не інтерактивний (!) І його батьківський процес називається rshdабо sshd. Таким чином , ви можете почати ~/.bashrcз

if [[ $- != *i* ]]; then
  . ~/.profile
  return
fi

Zsh завжди читає, ~/.zshenvколи воно починається. Використовуйте обережно, оскільки це читається кожним екземпляром zsh, навіть коли це піддіаграма, де ви встановили інші змінні. Якщо zsh - ваша оболонка для входу, і ви хочете використовувати її для встановлення змінних лише для віддалених команд, використовуйте захист: встановіть деяку змінну в ~/.profile, наприклад MY_ENVIRONMENT_HAS_BEEN_SET=yes, і перевірте цей захист перед читанням ~/.profile.

if [[ -z $MY_ENVIRONMENT_HAS_BEEN_SET ]]; then emulate sh -c '~/.profile'; fi

Справа графічних логінів

Багато дистрибутивів, диспетчери дисплеїв та настільних комп’ютерів організовують запуск ~/.profileабо шляхом явного джерела сценаріїв запуску, або за допомогою оболонки входу.

На жаль, не існує загального методу обробки комбінацій distro / DM / DE, де ~/.profileне читається.

Якщо ви використовуєте традиційний сеанс, розпочатий ним ~/.xsession, це місце, де ви повинні встановити змінні середовища; зробіть це за допомогою джерела ~/.profile(тобто . ~/.profile). Зауважте, що в деяких налаштуваннях сценарії запуску робочого середовища ~/.profileзнову будуть джерелами .


що робить case $- in *i*)?
qodeninja

2
@qodeninja Виконує наступні вказівки (до відповідності ;;або esac), якщо $-відповідає шаблону *i*, тобто якщо він $-містить i, тобто якщо оболонка є інтерактивною.
Жил "ТАК - перестань бути злим"

$-- це рядок із заданих на даний момент параметрів оболонки. (як set -x). iозначає інтерактивну оболонку.
Пітер Кордес

Ви не можете просто створити загальний файл, скажімо ~/.config/env, навіть без емуляції?
Кевін Саттл

1
@ StéphaneChazelas Це пуристський погляд. Я зберігаю свою .profileсумісність із досить старими снарядами Борна, але я визнаю, що деяким людям просто все одно. Я не маю нічого проти того, щоб люди припускали, що sh = bash для власних файлів, мені байдуже, лише якщо вони публікують #!/bin/shскрипт, який використовує функції bash.
Жил "ТАК - перестань бути злим"

4

Наскільки мені відомо, не існує стандартного дистрибутива та агностики для встановлення змінних середовища.

Найбільш поширеним і стандартом де - факто , як видається, /etc/profileі ~/.profile. Другим найпоширенішим, здається, є /etc/environmentі ~/.pam_environment.

Мені здається, всю документацію, яку я знайшов, ви теж знайшли. Я перелічу їх тут будь-коли для інших читачів.

  • Debian рекомендує /etc/profileта ~/.profile( посилання ).
  • Ubuntu рекомендує /etc/environmentта ~/.pam_environment( посилання ).
  • Arch Linux серед інших згадує /etc/profileі /etc/environment( посилання ).

Бонус: текст, який ставить під сумнів використання та / або неправильне використання /etc/environmentв debian ( посилання , остання версія 2008 р.).


Незалежно від файлу, який ви використовуєте, ви все ще натикаєтесь на несумісний синтаксис між різними оболонками.
Джозеф Р.

1
@JosephR. не більшість оболонок зберігають зворотну сумісність sh? Поки ви будете дотримуватися POSIX, я б подумав, що ви будете добре ...
evilsoup

1
AFAIK, ви не можете призначити змінні в cshі друзями POSIX способом (вам потрібно щось на зразок setабо setenv)
Джозеф Р.

0

Я додав такий сценарій ~ / bin / agnostic_setenv:

#!/bin/csh -f
set args = ($*)
if ($#args == 1) then
   echo "export $args[1]="
   exit 0
endif

if ($#args == 2) then
   if ("$args[1]" =~ *csh*) then 
      echo "setenv $args[2]"
      exit 0
   else
      echo "export $args[1]=$args[2]"
      exit 0
   endif
endif

echo "setenv $args[2] $args[3]"

І в ~ / .perl-homedir я використовую:

eval `${HOME}/bin/agnostic_setenv $shell PERL_HOMEDIR 0`

Симіліарний сценарій для agnostic_unsetenv:

#!/bin/csh -f
set args = ($*)
if ($#args == 1) then
   echo "export $args[1]"
   exit 0
endif

echo "unsetenv $args[2]"
exit 0
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.