11

Вот мотивация для вопроса:

Я использую Ubuntu 12.04 LTS 2 с рабочим столом Unity. В моем файле .bashrc я добавляю несколько каталогов к моей переменной PATH и определяю несколько переменных среды, таких как JAVA_HOME. Когда я запускаю приложения из терминала (работает bash, моя оболочка по умолчанию), это прекрасно работает, но для некоторых из ярлыков, использующих панель запуска Unity, они запускают приложения, которые, похоже, определены для использования #!/bin/sh, который имеет псевдоним /bin/dash, и они не собирают содержимое ни ~ /.bashrc, ни ~ /.profile.

Я полагаю, что я мог бы изменить все эти сочетания клавиш, чтобы использовать /bin /bash вместо /bin /sh, чтобы заставить его воспринимать изменения .bashrc, но это выглядит очень странно.

Учитывая, что Ubuntu 12.04 (по умолчанию) использует псевдонимы /bin /sh для /bin /dash и что моя оболочка по умолчанию - /bin /bash, есть ли единственное место, где я могу изменить PATH и определить переменные окружения, если они мне нужны? присутствовать при всех этих обстоятельствах:

  1. Всякий раз, когда я создаю оболочку bash без входа в систему (используя терминал в единстве)
  2. Всякий раз, когда я создаю оболочку входа в систему bash (например, вход в систему удаленно через ssh)
  3. Всякий раз, когда я использую панель запуска приложений Unity (учитывая, что панель запуска использует /bin /sh).
  4. Всякий раз, когда выполняется задание cron (учитывая, что SHELL = /bin /sh в /etc /crontab).

Если я правильно понимаю, я предполагаю, что:

  • (1)/(2) и (3)/(4) различаются, потому что (1)/(2) - bash, а (3)/(4) - dash.
  • (1) и (2) различаются, потому что файлы, которые bash выбирает для загрузки, отличаются в зависимости от того, является ли это оболочкой входа в систему.
  • (3) и (4) различаются, потому что (3) придет в какой-то момент после того, как я войду в систему (и, следовательно, ~/.profile будет получен одним из его родительских процессов, в то время как (4) придет в некоторый Точка, когда я не вошел в систему, и, следовательно, ~/.profile не будет прочитан.

(Я не удивлюсь, если другие факторы также имеют значение, например, является ли оболочка интерактивной, так что, возможно, есть и другие комбинации, которые я даже не ожидал ...Я рад, что мой вопрос "улучшился" в этом случае.)

Я ожидаю, что в какой-то момент кто-то должен был создать какое-то руководство, которое расскажет вам, как / где модифицировать переменные среды независимым от оболочки способом (или, по крайней мере, совместимым с dash / bash способом)...Я просто не могу найти правильные условия поиска, чтобы найти такое руководство.

Решения или указатели на решения приветствуются!

Обновлено:

  • Пояснение: это пользователь Ubuntu по умолчанию, созданный в процессе установки 12.04, так что ничего особенного. Это есть ~/.profile (что явно источники ~/.bashrc), и только ~/.bash * файлы присутствуют .bashrc, .bash_history и .bash_logout ... так нет нет .bash_profile.
  • Акцент на области применения: меня не волнуют никакие оболочки, кроме интерактивной оболочки по умолчанию (bash) и любого сценария, который использует /bin /sh (с псевдонимом dash), поэтому нет необходимости усложнять это чем-то дополнительным для Tcsh /КШ /ЗШ /и т.д.. служба поддержки.

3 ответа3

9

Вызов Shell - сложная вещь. Man-страницы bash и dash имеют разделы INVOCATION по этому поводу.

В итоге они говорят (есть более подробная информация на странице руководства, вы должны прочитать это):

When bash is                   | it reads
-------------------------------|----------
login shell                    | /etc/profile and then the first of ~/.bash_profile, ~/.bash_login or ~/.profile that exists.
                               |
interactive non-login shell    | /etc/bash.bashrc then ~/.bashrc
                               |
non-interactive shell          | The contents of $BASH_ENV (if it exists)
                               |
interactive (as "sh")          | The contents of $ENV (if it exists)

-

When dash is                   | it reads
-------------------------------|---------
login shell                    | /etc/profile then .profile
                               |
interactive shell              | The contents of ENV (it it exists, can be set in .profile as well as in initial environment)

Я не знаю о других снарядах, так как никогда не использую их. Лучше всего было бы установить пару переменных среды так, чтобы они указывали на сценарий общего местоположения, и вручную указывать источник (в случае необходимости) в паре случаев, которые не охватываются.

3

Итак, есть несколько способов подойти к этому. Многие люди будут либо:

а. Имейте один файл, который имеет общие черты для всех ваших оболочек в стиле sh, скажем .shcommon и в каждом из .profile .bashrc .kshrc et cetra, просто поставьте его с помощью . .shcommon

б. Поместите все в .profile и получите это из других файлов.

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

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

Во-первых, все, что мне нужно, идет в .profile Поскольку у меня есть некоторые специфичные для bash и ksh вещи, я определяю текущее имя оболочки, используя следующее:

# get name of current shell
# strip leading - from login shell
export SHELLNAME="${0#-}"

и затем есть команды для определенных оболочек в чем-то вроде следующего (некоторые предпочитают оператор case).

if [ "$SHELLNAME" = 'bash' ]
then
    shopt -s checkwinsize

elif [ "$SHELLNAME" = 'ksh' ]
then
    stty erase ^?
fi

Если у меня есть команды, которые должны выполняться только в интерактивных оболочках, я использую следующее:

# check for interactive flag i in shell options $-
# in bash and ksh you could use the following, but breaks in dash
# if [[ $- == *i* ]]
if [ "$(echo $- | grep i)" != "" ]
then
  fortune
fi

Вещи, которые распространены во всех оболочках стиля sh, например, PATH могут просто идти сверху.

Затем я использую символические ссылки для загрузки этого файла во все оболочки sh-style:

ln -s .profile .bashrc
ln -s .profile .kshrc

Пара замечаний: если у вас есть .bash_profile , то bash загрузит его вместо .profile но dash и ksh все равно загрузят .profile Это может быть частью вашей проблемы.

Кроме того, вы можете рассмотреть возможность использования #!/bin/bash в ваших скриптах вместо #!/bin/dash если вы действительно не хотите POSIX-совместимые скрипты. В bash есть много дополнительных функций, которые очень хороши, и dash или bash вызываются, так как sh отключит многие из этих функций.

Кроме того, справочная страница bash хорошо объясняет, когда загружаются файлы .profile и .bashrc . Аналогичные правила применяются к ksh. dash загружает .profile при входе в систему и позволяет загружать файл при запуске интерактивных оболочек, который задается с помощью переменной среды ENV в .profile (проверьте страницу руководства dash и найдите .profile).

0

Поскольку случаи (1) и (2) решаются путем поиска переменных окружения в .bashrc и .profile, реальный вопрос заключается в том, «как называется файл, в котором я получаю эти же переменные для (3) и (4).

Похоже, что есть ответ на часть (3) вопроса (как мне получить переменную среды для импорта на рабочий стол Unity) в askubuntu. Здесь предлагается создать файл ~/.xsessionrc, который будет получен из /etc /X11 /Xsession. (Я попробовал это, и это похоже на работу ... ууу!)

Я все еще озадачен тем, что делать для (4). Конечно, если я создаю задание cron (или демон), я могу заменить '/bin/foo' на что-то вроде 'bash -i -c /bin/foo', чтобы заставить его использовать bash для загрузки правильных переменных среды, но это также означает, что мне придется возиться с любыми сторонними инструментами, которые могут устанавливать задачи демона или задачи cron от моего имени. ЮК.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .