Куди я повинен експортувати змінну середовища, щоб усі комбінації bash / dash, інтерактивних / неінтерактивних, login / non-login підбирали її?


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) - баш і (3) / (4) - тире.
  • (1) та (2) відрізняються тим, що файли, які bash вибирає для завантаження, відрізняються залежно від того, чи це оболонка входу.
  • (3) і (4) відрізняються тим, що (3) з’явиться в якийсь момент після входу в систему (і, отже, ~ / .profile буде створений одним із його батьківських процесів, тоді як (4) з'явиться в деяких момент, коли я не ввійшов у систему, а значить ~ / .profile не буде прочитаний.

(Я не був би здивований, якщо важливі й інші фактори, такі як оболонка інтерактивна чи ні, тому, ймовірно, є більше комбінацій, яких я навіть не очікував ... Я радий, що моє запитання "покращилося " в такому разі.)

Я б очікував, що в якийсь момент хтось, мабуть, зробив якийсь посібник, який розповість вам, як / де змінювати змінні середовища в незалежному від оболонки способі (або, принаймні, тире / баш-сумісному способі) ... Я просто можу ' не можу знайти потрібні пошукові терміни, щоб знайти такий путівник.

Рішення чи покажчики на рішення високо оцінені!

Оновлено:

  • Пояснення: Це користувач Ubuntu за замовчуванням, створений процесом встановлення 12.04, тому нічого фантазійного. У нього є ~ / .profile (явно джерела ~ / .bashrc), і єдиними присутніми файлами ~ / .bash * є .bashrc, .bash_history та .bash_logout ... так що немає .bash_profile.
  • Акцент на області застосування: Мені не дуже важливо будь-які оболонки, окрім інтерактивної оболонки за замовчуванням (bash) та будь-якого сценарію, який трапляється використовувати / bin / sh (aliase to dash), тому немає необхідності ускладнювати це чим-небудь додатковим для tcsh / ksh / zsh / тощо. підтримка.

2
Помістіть його в один файл, а потім дозвольте іншим rc-файлам джерело його.
konsolebox

Згідно з даною сторінкою тире, на якій я маю тут, слід прочитати $ HOME / .profile для оболонок для входу.
Ітан Рейснер

@konsolebox Які rc файли? AFAICT, тире не має файлу rc. І як я вже зазначив, тире, схоже, не збирає вміст ~ / .profile.

@EtanReisner Так, це питання. Якщо тире не працює як оболонка для входу (а значить, ~ / .profile не отримується), що тоді?

@Mickalot Ти інтерактивно працюєш з тире? Якщо не спробувати додати до нього опцію -l.
konsolebox

Відповіді:


9

Виклик оболонки - трохи складна річ. На сторінках "bash and dash man" є 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)

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


На жаль, суть цієї проблеми - це те, чого не вистачає у вашій таблиці тире. Коли робочий стіл Unity викликає будь-який скрипт, який починається з #! / Bin / sh, він запускає (я вважаю, що це) неінтерактивну оболонку тире. Отже, питання: як я можу зробити ті самі змінні середовища доступними там, які є скрізь у матриці?

Правильно. Я думаю, що тому bash додав BASH_ENV для цього слота. Зважаючи на те, що на тире не працює нічого в цьому слоті, я не впевнений, що ви можете вирішити цю проблему, не впливаючи на зміну середовища програми, яка запускає тире (такий, що тире успадковує його). Для цього знадобиться встановити змінні середовища у вашому X-середовищі, де саме тут вступає коментар .xsession (rc) від @Mickalot. Це все ще залишає, як він зазначив, пункт четвертий залишив (але я вважаю, що це насправді дещо навмисне).
Ітан Рейснер

Оскільки я перебуваю на Ubuntu 12.04 LTS, cron є насправді pixie-cron, тож я можу визначити env змінні у своєму файлі crontab ... Я здогадуюсь SHELL = / bin / bash та BASH_ENV = ~ / .bashrc повинен це робити?

3

Отже, існує кілька способів наблизитись до цього. Багато людей або:

а. Майте один файл, у якому є речі, спільні для всіх ваших оболонок у стилі sh, наприклад, .shcommonта у кожній із цих програм .profile .bashrc .kshrc, просто введіть це. .shcommon

б. Покладіть усе в .profileі джерело цього з інших файлів.

Речі, необхідні для конкретних оболонок або для інтерактивних проти неінтерактивних оболонок, можуть потім перейти у відповідний файл перед початком пошуку .shcommon

Особисто мені не подобається керувати кількома файлами. Отже, я використовую такий підхід:

По-перше, все, що мені потрібно, полягає в тому, що у .profile мене є деякі специфічні для bash і ksh речі, я визначаю поточну назву оболонки, використовуючи наступне:

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

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

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:

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

Кілька бічних нотаток, якщо у вас є .bash_profile, то bash завантажить це замість, .profileале тире і ksh все одно завантажують .profile Це може бути частиною вашої проблеми.

Крім того, ви можете розглянути можливість використання #!/bin/bashу своїх сценаріях замість того, #!/bin/dashякщо ви дійсно не хочете сумісних з POSIX сценаріїв. bash має безліч додаткових функцій, які дуже приємні, і тире або bash викликаються, оскільки sh відключить багато з цих функцій.

Крім того, сторінка bash man чудово пояснює, коли завантажується .profileпорівняно .bashrc. Подібні правила стосуються ksh. тире завантажується .profileпри вході в систему і дозволяє завантажувати файл під час запуску інтерактивних оболонок, що вказано за допомогою ENVзмінної середовища в .profile(також перевірте сторінку "dash man" та шукайте .profile).


Не могли б ви просто перевірити $ 0 на ім'я оболонки? Чи є снаряди / випадки, коли це не працює?
Ітан Рейснер

Так само, чи перевірка на i в $ - недостатньо для інтерактивного тесту оболонки? (Це буде спрацьовувати на інтерактивних оболонках, не надаючи я, але це може бути або не бути небажаним побічним ефектом.)
Етан Рейснер,

@Etan: Хрм, я знаю, що вперше спробував $0і зіткнувся з проблемами ... Я, здається, не пам'ятаю, що саме вони були. Вхід безпосередньо в консоль відображається $0як -bashзамість цього, bashале це можна виправити.

@Etan: Так, перевірка наявності в мене $-також буде працювати. Мені довелося б подумати, коли у вас буде інтерактивна оболонка без тти? У вашому рішенні чомусь краще «відчуваються», я можу це змінити.

-В -bashозначає «Шелл» , але так , вам потрібно буде урахуванням , що в тих місцях , де ви перевірити значення або хочете , щоб відобразити його кому - то.
Ітан Рейснер

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 від мого імені. Юк.

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