LINUX.ORG.RU

Пользовательские переменные окружения

 , , , ,


0

5

Как задаются пользовательские переменные окружения?

Мне требуется аналог переменным окружения пользователя в оффтопике: независимо от интерпретатора скриптов, чтобы для пользователя были некоторые глобальные переменные окружения.

BASH игнорирует .profile

SH игнорирует .bashrc

BASH и SH игнорируют .pam_environment

Как правильно задать переменные окружения?

Deleted
Ответ на: комментарий от alozovskoy

/etc/profile - это вроде общесистемные. Я надеялся чисто для одного пользователя. (по крайней мере я не хочу прописывать тот же GOPATH сразу в несколько конфигурационных файлов для каждого шелла).

И будет крайне обидно, если такового нет.

Deleted
()
Последнее исправление: merhalak (всего исправлений: 2)

Странно, .profile должен работать.

Но используй unix-way, городи костыли. Создай файл .profile, а в .bashrc добавь строку source ~/.profile.

anonymous
()
Ответ на: комментарий от anonymous

В комментариях .bashrc написано, что если существует .bashrc или .bash_profile, то .profile игнорируется.

Идиотизм.

Deleted
()
Ответ на: комментарий от Deleted

Можно добавить в /etc/profile что-то вроде

[ -f ~/.megaFile ] && source ~/.megaFile

И тогда для нужного пользователя положить файл с требуемым содержимым.

alozovskoy ★★★★★
()

Как правильно задать переменные окружения?

В ~/.profile. Во известных мне поставках ГНУ он обрабатывается правильно (из коробки, то есть если вы ничего не поломали).

BASH игнорирует .profile

Если имеется .bash_profile или .bash_login, которые, очевидно создавать не надо.

SH игнорирует .bashrc

Любая входная оболочка (login shell), в том числе Баш, игнорирует .bashrc.

Zmicier ★★★★★
()
Ответ на: комментарий от anonymous

Создай файл .profile, а в .bashrc добавь строку source ~/.profile.

Лютая глупость — не нужно при каждом запуске Баша выполнять то, что делается единожды при входе в систему.

Особенно учитывая, что нормальные ~/.profile содержат условный source $HOME/.bashrc, то есть вы залетите в бесконечный цикл.

Zmicier ★★★★★
()
Ответ на: комментарий от alozovskoy

добавить в /etc/profile что-то вроде
[ -f ~/.megaFile ] && source ~/.megaFile

1. Для этого существует ~/.profile, который все оболочки и так должны читать, а если не читают, надо искать почему.

2. Это может не работать — source — не самая универсальная конструкция, точка универсальней.

Zmicier ★★★★★
()
Ответ на: комментарий от Deleted

В комментариях .bashrc написано, что если существует .bashrc или .bash_profile, то .profile игнорируется.

Не верю.

Zmicier ★★★★★
()
Ответ на: комментарий от Zmicier

а если не читают, надо искать почему

ТС Сказал что не читают, я пляшу от его информации

source — не самая универсальная конструкция, точка универсальней.

Это разве не синонимы? Хотел бы почитать про различия, дашь ссылку на мануал?

alozovskoy ★★★★★
()
Ответ на: комментарий от alozovskoy

Вечером перепроверю и напишу сюда.

Deleted
()
Ответ на: комментарий от alozovskoy

source — не самая универсальная конструкция, точка универсальней.

Это разве не синонимы?

source — синоним к . в некоторых языках, к примеру, в Debian ASH’е его нет.

ТС Сказал что не читают, я пляшу от его информации

И надо выяснить почему, а не костылить.

Zmicier ★★★★★
()
Ответ на: комментарий от Zmicier

И какие есть варианты? Смотреть исходники или писать разработчику\мейнтейнеру?

alozovskoy ★★★★★
()

man bash

1.

When bash is invoked as an interactive login shell, or as a non-interactive shell with the --login option, it first reads and executes commands from the file /etc/profile, if that file exists. After reading that file, it looks for ~/.bash_profile, ~/.bash_login, and ~/.profile, in that order, and reads and executes commands from the first one that exists and is readable.

Т.е. единожды при логине исполняется /etc/profile и первый встреченный из эти: ~/.bash_profile, ~/.bash_login, and ~/.profile

2.

When an interactive shell that is not a login shell is started, bash reads and executes commands from ~/.bashrc, if that file exists.

Каждый раз при запуске просто шелла (и, напр., эмулятора виртуального терминала (xterm\gnome-terminal) bash исполняет ~/.bashrc

When bash is started non-interactively, to run a shell script, for example, it looks for the variable BASH_ENV in the environment, expands its value if it appears there, and uses the expanded value as the name of a file to read and execute.

Т.е. при запуске bash-скрипта никакой ~/.bashrc не выполняется, но может использоваться BASH_ENV (которая может быть назначена где-то раньше - при логине или при запуске шелла)

3.

If bash is invoked with the name sh, it tries to mimic the startup behavior of historical versions of sh as closely as possible, while conforming to the POSIX standard as well. When invoked as an interactive login shell, or a non-interactive shell with the --login option, it first attempts to read and execute commands from /etc/profile and ~/.profile, in that order.

sh-совместимость. При запуске баша по симлинку с sh для логина исполняются /etc/profile and ~/.profile Стоит сравнить с п.1, в котором ~/.profile может не исполняться, при наличии ~/.bash_profile или ~/.bash_login !

4.

When invoked as an interactive shell with the name sh, bash looks for the variable ENV, expands its value if it is defined, and uses the expanded value as the name of a file to read and execute.

Аналог п.2 для sh-совместимого запуска. Запуск шелла как sh не читает определенные rc-файлы, только указанный в переменной ENV

A non-interactive shell invoked with the name sh does not attempt to read any other startup files.

Делаю вывод, что при запуске sh-скриптов (в частности тех, у которых шебанг #!/usr/bin/sh), никакие дополнительные rc-файлы не исполняются, используется только уже существующее окружение.

Deleted
()
Последнее исправление: Deleted (всего исправлений: 1)
Ответ на: комментарий от Deleted

Из этого могу сделать вывод, что ~/.bash_profile мешает задать переменные окружения юзеру в одном месте, здесь: ~/.profile

Полагаю, если не используется баш-специфичная кастомизация, то нужно удалить эти ~/.bash_profile и ~/.bash_login , оставив только ~/.profile и в нем задавать переменные окружения для юзера.

Deleted
()
Ответ на: комментарий от Zmicier

1. Для этого существует ~/.profile, который все оболочки и так должны читать, а если не читают, надо искать почему.

Оказывается, по man bash, ~/.profile не читается, если bash задан как логин-шелл и существуют файлы (~/.bash_profile ИЛИ ~/.bash_login).

Например, в федоре ~/.bash_profile есть по дефолту. А в убунте нет.

Deleted
()
Последнее исправление: Deleted (всего исправлений: 2)
Ответ на: комментарий от Deleted

~/.profile не читается, если bash задан как логин-шелл и существуют файлы (~/.bash_profile ИЛИ ~/.bash_login)

Я это выше уже́ писал.

в Федоре ~/.bash_profile есть по дефолту.

И что в нем написано? Должно быть среди прочего и . $HOME/.profile, если мне не изменяет память.

Zmicier ★★★★★
()
Ответ на: комментарий от Zmicier

Я это выше уже́ писал.

Да, точно

Должно быть среди прочего и . $HOME/.profile,

Вот что там в дефолте

# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
	. ~/.bashrc
fi

# User specific environment and startup programs

PATH=$PATH:$HOME/.local/bin:$HOME/bin

export PATH

На самом деле, если бы было как ты сказал, по дефолту, то это противоречило бы man bash. Можно самому закастомайзить, написав по аналогии . ~/.profile . Мне кажется, так и надо сделать

Deleted
()
Последнее исправление: Deleted (всего исправлений: 1)
Ответ на: комментарий от Deleted

И правильней добавлять в .bash_profile загрузку .profile перед bashrc:

if [ -f ~/.profile ]; then
	. ~/.profile
fi
if [ -f ~/.bashrc ]; then
	. ~/.bashrc
fi

Deleted
()

Еще порадовал http://superuser.com/a/789499 :)

Conclusion? Shells are a pain. Environment variables are a pain. Distribution-specific compile-time options are an immense pain in the ass.

Deleted
()
Ответ на: комментарий от Deleted

Вот что там в дефолте

Забавно. Спасибо, буду иметь в виду.

На самом деле, если бы было как ты сказал, по дефолту, то это противоречило бы man bash.

bash(1) не описывает, что́ должно быть в rc-сценариях, поэтому противоречить ему они не могут.

Но я понял, что вы хотели сказать, и если примем такую формулировку, то сейчас (с . ~/.bashrc) оно противоречит в той же самой степени.

Zmicier ★★★★★
()
Ответ на: комментарий от Zmicier

Да, согласен. superuser.com/a/789499 вся тема прекрасна, например «Have a ~/.bashrc that performs any shell-specific setup, guarded with a check for interactive mode to avoid breaking things like sftp on Debian (where bash is compiled with the option to load ~/.bashrc even for non-interactive shells

Одни грабли

Deleted
()

У тебя в тегах правильный ответ - PAM. Не зависит ни от каких интерпретаторов и способа входа (если правильно настроить).

BASH и SH игнорируют .pam_environment

Это нормально. Файл читается при логине. В конфигурации PAM его ещё нужно разрешить, если в дистрибутиве это не сделано.

anonymous
()
Ответ на: комментарий от Deleted

Похоже я затупил. Надо будет проверить, хотя вроде я делал перелогин в X-ах, чтобы перезагрузить .profile.

У меня на компе есть только .bashrc и .profile, если я правильно помню. У меня Debian netinstall (с выбором Mate desktop), почти ванильный.

Deleted
()
Последнее исправление: merhalak (всего исправлений: 1)
Ответ на: комментарий от anonymous

Оп, оп. А как это? И при логине в консоли, или X-ы тоже считаются?

Хотя пойду почитаю, а то что-то совсем обнаглел.

Deleted
()
Последнее исправление: merhalak (всего исправлений: 1)

PtiCa alozovskoy Zmicier я покопался. Заметил зависимость: .profile работает. Но! Только в терминале, в X-ах работать не желает. Как будто игнорирует при логине. Похоже, что придётся разбираться с PAM.

Deleted
()
Ответ на: комментарий от Deleted

Можешь привести на пастбин содержание всех упомянутых в ветке rc-файлов, если такого файла нет - упомяни что отсутствует. Оч странно.

Deleted
()
Ответ на: комментарий от Deleted

тебе же GOPATH и GOBIN нужны? Попробуй так

GOPATH=$HOME/Документы/workspace/gopath
GOBIN=$GOPATH/bin

export GOPATH
export GOBIN

UPD Это не сработает, я ошибся

Deleted
()
Последнее исправление: Deleted (всего исправлений: 1)
Ответ на: комментарий от Deleted

Фишка в том, что Sublime использует sh (как я понял), а в консоли bash. Но синхронизировать каждый раз это говно мне лениво.

Deleted
()
Ответ на: комментарий от Deleted

.profile работает. Но! Только в терминале, в X-ах работать не желает.

Это не нормально. Покажите ваш Xsession. Где он — зависит от того, что у вас за экранный диспетчер: для GDM’а, к примеру, — /etc/gdm/Xsession, кажется.

Zmicier ★★★★★
()
Последнее исправление: Zmicier (всего исправлений: 2)
Ответ на: комментарий от Deleted

Фишка в том, что Sublime использует sh (как я понял), а в консоли bash.

А какое это здесь может иметь значение?

Zmicier ★★★★★
()
Ответ на: комментарий от Zmicier

Хочу задать GOPATH глобально, а не per-project.

Deleted
()
Ответ на: комментарий от Zmicier
#!/bin/sh
#
# /etc/X11/Xsession
#
# global Xsession file -- used by display managers and xinit (startx)

# $Id: Xsession 967 2005-12-27 07:20:55Z dnusinow $

set -e

PROGNAME=Xsession

message () {
  # pretty-print messages of arbitrary length; use xmessage if it
  # is available and $DISPLAY is set
  MESSAGE="$PROGNAME: $*"
  echo "$MESSAGE" | fold -s -w ${COLUMNS:-80} >&2
  if [ -n "$DISPLAY" ] && which xmessage > /dev/null 2>&1; then
    echo "$MESSAGE" | fold -s -w ${COLUMNS:-80} | xmessage -center -file -
  fi
}

message_nonl () {
  # pretty-print messages of arbitrary length (no trailing newline); use
  # xmessage if it is available and $DISPLAY is set
  MESSAGE="$PROGNAME: $*"
  echo -n "$MESSAGE" | fold -s -w ${COLUMNS:-80} >&2;
  if [ -n "$DISPLAY" ] && which xmessage > /dev/null 2>&1; then
    echo -n "$MESSAGE" | fold -s -w ${COLUMNS:-80} | xmessage -center -file -
  fi
}

errormsg () {
  # exit script with error
  message "$*"
  exit 1
}

internal_errormsg () {
  # exit script with error; essentially a "THIS SHOULD NEVER HAPPEN" message
  # One big call to message() for the sake of xmessage; if we had two then
  # the user would have dismissed the error we want reported before seeing the
  # request to report it.
  errormsg "$*" \
           "Please report the installed version of the \"x11-common\"" \
           "package and the complete text of this error message to" \
           "<debian-x@lists.debian.org>."
}

# initialize variables for use by all session scripts

OPTIONFILE=/etc/X11/Xsession.options

SYSRESOURCES=/etc/X11/Xresources
USRRESOURCES=$HOME/.Xresources

SYSSESSIONDIR=/etc/X11/Xsession.d
USERXSESSION=$HOME/.xsession
USERXSESSIONRC=$HOME/.xsessionrc
ALTUSERXSESSION=$HOME/.Xsession
ERRFILE=$HOME/.xsession-errors

# attempt to create an error file; abort if we cannot
if (umask 077 && touch "$ERRFILE") 2> /dev/null && [ -w "$ERRFILE" ] &&
  [ ! -L "$ERRFILE" ]; then
  chmod 600 "$ERRFILE"
elif ERRFILE=$(tempfile 2> /dev/null); then
  if ! ln -sf "$ERRFILE" "${TMPDIR:=/tmp}/xsession-$USER"; then
    message "warning: unable to symlink \"$TMPDIR/xsession-$USER\" to" \
             "\"$ERRFILE\"; look for session log/errors in" \
             "\"$TMPDIR/xsession-$USER\"."
  fi
else
  errormsg "unable to create X session log/error file; aborting."
fi

exec >>"$ERRFILE" 2>&1

echo "$PROGNAME: X session started for $LOGNAME at $(date)"

# sanity check; is our session script directory present?
if [ ! -d "$SYSSESSIONDIR" ]; then
  errormsg "no \"$SYSSESSIONDIR\" directory found; aborting."
fi

# Attempt to create a file of non-zero length in /tmp; a full filesystem can
# cause mysterious X session failures.  We do not use touch, :, or test -w
# because they won't actually create a file with contents.  We also let standard
# error from tempfile and echo go to the error file to aid the user in
# determining what went wrong.
WRITE_TEST=$(tempfile)
if ! echo "*" >>"$WRITE_TEST"; then
  message "warning: unable to write to ${WRITE_TEST%/*}; X session may exit" \
          "with an error"
fi
rm -f "$WRITE_TEST"

# use run-parts to source every file in the session directory; we source
# instead of executing so that the variables and functions defined above
# are available to the scripts, and so that they can pass variables to each
# other
SESSIONFILES=$(run-parts --list $SYSSESSIONDIR)
if [ -n "$SESSIONFILES" ]; then
  set +e
  for SESSIONFILE in $SESSIONFILES; do
    . $SESSIONFILE
  done
  set -e
fi

exit 0

# vim:set ai et sts=2 sw=2 tw=80:
Deleted
()
Ответ на: комментарий от Zmicier

Заодно Xsession.options

# $Id: Xsession.options 189 2005-06-11 00:04:27Z branden $
#
# configuration options for /etc/X11/Xsession
# See Xsession.options(5) for an explanation of the available options.
allow-failsafe
allow-user-resources
allow-user-xsession
use-ssh-agent
use-session-dbus

Deleted
()
Ответ на: комментарий от Deleted

/etc/X11/Xsession

У вас что, вовсе нет экранного диспетчера? Вы Иксы через startx или подобным образом запускаете?

Если не так, то это не тот файл.

Zmicier ★★★★★
()
Ответ на: комментарий от Deleted

В /etc/pam.d/common-auth пропиши

auth	required			pam_env.so user_envfile=.environment user_readenv=1
и будет везде. Этот файл есть в Debian, YMMV.

anonymous
()
Ответ на: комментарий от Deleted

Увидел применение в Ubuntu, а потом man 8 pam_env прочитал. По большому счёту, user_readenv=1 только нужно, потому что этот модуль из коробки используется, но с глобальным файлом окружение (типа /etc/environment).

anonymous
()
Ответ на: комментарий от anonymous

Раз уж через pam_env.so, то делать это надо в session, а не в auth.

bigbit ★★★★★
()
Ответ на: комментарий от Deleted

Как строка с .profile выглядит в Xsession gdm?

# First read /etc/profile and .profile
test -f /etc/profile && . /etc/profile
test -f "$HOME/.profile" && . "$HOME/.profile"
# Second read /etc/xprofile and .xprofile for X specific setup
test -f /etc/xprofile && . /etc/xprofile
test -f "$HOME/.xprofile" && . "$HOME/.xprofile"

Файл целиком, если интересно.

Zmicier ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.