Чому інтерактивні оболонки в оболонках для входу в OSX за замовчуванням?


43

У Linux та, наскільки мені відомо, всі системи Unix, емулятори терміналів за замовчуванням працюють інтерактивні оболонки без входу. Це означає, що для bash, запущена оболонка:

Коли запускається інтерактивна оболонка, яка не є оболонкою для входу, bash зчитує та виконує команди з /etc/bash.bashrcта ~/.bashrc, якщо ці файли існують. Це може бути пригнічено за допомогою --norc параметра.

Параметр --rcfile файлу змусить bash читати та виконувати команди з файлу замість /etc/bash.bashrcта ~/.bashrc.

А для оболонок для входу:

Коли bash викликається як інтерактивна оболонка для входу, або як неінтерактивна оболонка з --loginможливістю, вона спочатку зчитує та виконує команди з файлу /etc/profile, якщо такий файл існує. Після прочитання цього файлу, він шукає ~/.bash_profile, ~/.bash_loginі ~/.profile, в такому порядку, і читає і виконує команду з першого, який існує і читаються.

--noprofileВаріант може бути використаний , коли оболонка запускається , щоб пригнічувати таку поведінку.

Однак у OSX оболонка за замовчуванням (що є bash), запущена в терміналі за замовчуванням (Terminal.app), фактично є джерелом ~/.bash_profileабо ~.profileіншим словом. Іншими словами, вона діє як оболонка входу.

Основне питання : Чому інтерактивна оболонка за замовчуванням оболонка для входу в OSX? Чому OSX вирішив це зробити? Це означає, що всі інструкції / підручники для речей на основі оболонок, в яких згадується зміна речей, ~/.bashrcвийдуть з ладу на OSX або навпаки ~/.profile. Тим не менш, хоча багато звинувачень можна вирівняти в Apple, наймання некомпетентних або ідіотських розрядів - це не одне з них. Імовірно, у них були вагомі причини для цього, так чому?

Підпитання: Чи реально запускає Terminal.app інтерактивну оболонку входу або вони змінили поведінку bash? Це специфічно для Terminal.app чи він не залежить від емулятора терміналу?


2
Terminal.app запускає оболонку входу. Я не знаю, чому Apple вирішила це зробити.
Жил "ТАК - перестань бути злим"

Відповіді:


33

Це, як передбачається, полягає в тому, що в момент отримання запиту на оболонку обидва .profileі .bashrcбули запущені. Конкретні деталі того, як ви дістанетесь до цього моменту, мають вторинну актуальність, але якщо жоден з файлів взагалі не запустився, у вас буде оболонка з неповними налаштуваннями.

Причина емуляторів терміналів для Linux (та інших систем на базі X) не потрібно запускати .profileсамостійно - це те, що вона, як правило, запускалася вже під час входу в X. Налаштування в, .profileяк передбачається, повинні бути такими, якими можуть бути успадковується підпроцесами, доки він виконується один раз під час входу в систему (наприклад, через .Xsession), будь-які подальші підзаголовки не потребують його повторного запуску.

Як пояснює сторінка вікі Debian, пов’язана Аланом Шутко:

"Чому тоді .bashrcвідокремлений файл .bash_profile? Це робиться з більшості історичних причин, коли машини були надзвичайно повільними порівняно з сьогоднішніми робочими станціями. Обробка команд у .profileабо .bash_profileможе зайняти досить тривалий час, особливо на машині, де багато роботи це потрібно робити за допомогою зовнішніх команд (pre-bash). Таким чином, вводяться складні команди початкового налаштування, які створюють змінні середовища, які можна передавати дочірнім процесам .bash_profile. Ставляться перехідні налаштування та псевдоніми, які не успадковуються в .bashrcтак що вони можуть бути повторно прочитано кожної субоболочка «.

Усі ті ж правила дотримуються і OSX, за винятком одного - графічний інтерфейс OSX не працює .profileпри вході в систему, мабуть, тому, що він має власний метод завантаження глобальних налаштувань. Але це означає, що термінальний емулятор на OSX дійсно потрібно запустити .profile(повідомляючи оболонці, яку він запускає, що це оболонка для входу), інакше ви отримаєте потенційно калічену оболонку.


Тепер, своєрідна нерозумна особливість bash, на яку не ділиться більшість інших оболонок, полягає в тому, що він не запускається автоматично, .bashrcякщо він запускається як оболонка для входу. Стандартний обхід для цього полягає в тому, щоб включити щось на зразок наступних команд у .bash_profile:

[[ -e ~/.profile ]] && source ~/.profile    # load generic profile settings
[[ -e ~/.bashrc  ]] && source ~/.bashrc     # load aliases etc.

Крім того, можливо, його взагалі немає .bash_profile, і просто включити в загальний .profileфайл якийсь специфічний для bash код, який потрібно запустити .bashrcза потреби.

Якщо OSX по замовчуванням .bash_profileабо .profile НЕ робити цього, то це спірно помилка. У будь-якому випадку, правильна обробка полягає в тому, щоб просто додати ці рядки .bash_profile.


Редагувати: Як зазначає strugee , оболонка за замовчуванням в OSX раніше була tcsh, поведінка якої в цьому відношенні набагато безпечніше: коли вона працює як інтерактивна оболонка входу, tcsh автоматично зчитує .profile і .tcshrc / .cshrc, і, таким чином, не потребує жодних обхідних шляхів, як .bash_profileтрюк показано вище.

Виходячи з цього, я на 99% впевнений, що неспроможність OSX поставити відповідний дефолт .bash_profile- це те, що, коли вони перейшли з tcsh на bash, люди в Apple просто не помітили цю маленьку бородавку в старті запуску bash. З tcsh подібні хитрощі не потрібні - запуск tcsh як оболонки для входу з емулятора терміналу OSX Just Plain Works і робить потрібні речі без таких збитків.


1
Дякую, я якось це все знав. Моє запитання: чому OSX вирішив налаштувати так, щоб зробити .bashrcневідповідними? Чому вони вирішили зробити всі оболонки для входу в оболонки? Наскільки я можу сказати, лише ваше останнє речення стосується цього і лише сказати, що це помилка.
terdon

1
Ні, проблема полягає в тому, що вони починають вхідні оболонки в своїх емуляторах терміналів. Точкові файли - це поведінка bash за замовчуванням, початкові оболонки входу будуть читати профіль тощо, а не bashrc і т.д.
terdon

2
Так, і я, і Алан пояснили, що це відбувається тому, що, на відміну від Linux, OSX не виконується, .profileколи користувач заходить у графічний інтерфейс, тому їм доведеться виконати його пізніше, щоб отримати змінні середовища $PATH, як правило, встановлені .profile, правильно налаштовані. . Той факт, що, як побічний ефект, це .bashrcне спричиняє виникнення, - це помилка; Ви можете посперечатися, чи це помилка в bash чи в OSX, але це не змінює факту, що правильна поведінка полягала б у тому, щоб забезпечити завантаження як змінних оточення, так .profileі налаштування bash config з .bashrc.
Ільмарі Каронен

1
Мати .bashrcджерело .profileбуло б поганою ідеєю, оскільки це призвело б до повторного запуску кожної підпакеті .profile. Якщо нічого іншого, це спричинить загальні .profileфразеологічні фрази, як, наприклад, export PATH = "$HOME/bin:$PATH"продовжувати передбачувані зайві записи $PATH. Мати .profileджерело .bashrcмає набагато більше сенсу, але лише після перевірки того, що оболонка, під якою він працює, насправді базується. Маючи .bash_profileджерело як .profile і .bashrc , як я запропонував вище, є ІМО, найбільш розумний варіант.
Ільмарі Каронен

2
І я кажу відповідь "чому вони використовують оболонку для входу?" «Тому що вони потребують в навантаження .profile», в той час як відповідь на питання «чому вони не джерело .bashrcз .profile, тоді?» це "тому що це помилка!" Серйозно, це не може бути навмисним рішенням; це лише те, що вони не помітили, мабуть, тому, що в екосистемі Mac оболонки є громадянами другого класу, з якими більшість користувачів не повинні мати справу. (Псал. Також відповідь Струже для історичного пояснення; це майже напевно регрес від переходу від tcsh на bash.)
Ilmari Karonen

14

Основна причина того, що X-термінальні програми за замовчуванням виконують оболонки без входу, - це те, що на початку часу ваша .Xsession запустила .profile для налаштування початкових елементів входу. Потім, оскільки це все було налаштовано, термінальним додаткам не потрібно було його запускати, вони могли запускати .bashrc. Обговорення того, чому це має значення, знаходиться на https://wiki.debian.org/DotFiles :

Візьмемо xdm як приклад. один день пієр повертається з відпустки і виявляє, що його системний адміністратор встановив xdm в системі Debian. Він увійде в систему просто, а xdm зчитує його .xsession файл та запускає флюкс-скриньку. Здається, все гаразд, поки він не отримає повідомлення про помилку в неправильній місцевості! Оскільки він переосмислює змінну LANG у своєму .bash_profile, а оскільки xdm ніколи не читає .bash_profile, його змінна LANG тепер встановлена ​​на en_US замість fr_CA.

Тепер наївне рішення цієї проблеми полягає в тому, що замість запуску "xterm" він міг налаштувати свого вікна-менеджера для запуску "xterm -ls". Цей прапор повідомляє xterm, що замість запуску звичайної оболонки він повинен запустити оболонку входу. У цьому налаштуванні xterm нереєструє / bin / bash, але він ставить "- / bin / bash" (а може бути "-bash") у вектор аргументу, тому bash діє як оболонка входу. Це означає, що щоразу, коли він відкриває новий xterm, він буде читати / etc / profile та .bash_profile (вбудована поведінка bash), а потім .bashrc (тому що .bash_profile говорить про це). Спочатку це може здатися прекрасним - його точкові файли не надто важкі, тому він навіть не помічає затримки - але є більш тонка проблема. Він також запускає веб-браузер безпосередньо зі свого меню fluxbox, і веб-браузер успадковує змінну LANG від fluxbox, який тепер встановлений у неправильній локалі. Тож хоча його xterms може бути нормальним, і все, що було запущено з його xterms, може бути нормальним, його веб-браузер все ще надає йому сторінки в неправильній місцевості.

У OS X користувальницьке середовище не запускається купою скриптів оболонки, а запуск не виводить .profile ні в який момент. (Це якась ганьба, оскільки це означає, що встановлювати змінні середовища, але таке життя набагато більше прикро, але таке життя.) Оскільки це не так, коли він би запускався .profile? Тільки якщо ти ввійшов? Це здається безглуздим, оскільки багато скриньок ніколи не будуть цілями ssh. Можна також змусити термінали запускати оболонки входу за замовчуванням, так що .profile буде запущений колись.

Що тоді з .bashrc? Це марно? Ні. Це все ще має мету, яку він мав у часи VT100. Він використовується в будь-який час, коли ви відкриваєте оболонку, крім відкриття вікна терміналу. Тож якщо ви користуєтеся Emacs або vi, або якщо ви користуєтеся су користувачем.


1
Сторінка Debian, яку ви цитуєте, пояснює, чому .profileджерела Debian .bashrc, а не чому OSX вирішили зробити всі оболонки для входу в оболонки за замовчуванням. Власне, ви відповідаєте на ще одне моє питання , і дякую! Однак ваша відповідь не пояснює вибір OSX, і цитата Debian тут абсолютно не має значення, наскільки я можу сказати (будь ласка, повідомте мене, якщо я просто пропускаю суть). OSX спосіб робить .bashrcі т. Д. Марними і не робить .profileбільше корисними.
тердон

4

Я не знаю, чому вони зробили б це. Однак ось моя здогадка.

Для початку варто відзначити, що в системі GNU / Linux, звичайно, ви можете перейти на vt1, vt2 і т. Д. Ви отримуєте там оболонку входу. У системі OS X немає еквівалента. Єдиний спосіб отримати доступ до підкладок UNIX - це через емулятор терміналу або через єдиний користувальницький режим (відмова від відповідальності: я ніколи фактично не використовував єдиний користувальницький режим; це IIRC, керований командним рядком, але я можу помилятися). Тому в OS X, що б за замовчуванням не було в емуляторі, це за замовчуванням для всієї системи.

Тепер, чому б ви зробили за замовчуванням оболонку для входу? Є кілька (читайте: не багато) причин, які я можу думати, щоб це зробити.

  • Це забезпечує постійний досвід роботи користувачів, якщо ви введете SSH у вікно. (Особливо важливо для серверного видання OS X - імовірно, якщо ви працюєте з сервером OS X, ви новачок.)
  • За замовчуванням оболонка OS X раніше tcsh. Це приблизно настільки ж дике здогад, як ви можете отримати, але може бути, що tcshзазвичай щось робилося, коли запускався як оболонка для входу, а історичний зразок застряг. (Я сумніваюся в цьому, хоча - можливо, хтось із старих постійних людей міг би сказати нам.)
  • "Ми Apple. Ми є постачальниками найбільшої дистрибуції UNIX на планеті. Не має значення, наскільки тривіальні наші причини; якщо ми приймемо рішення, ваш інструмент повинен з цим боротися".

Чесно кажучи, я використовую Дарвін близько 6 років і не можу відповісти належним чином на це питання. Для мене це теж не має сенсу.

Щоб відповісти на ваше запитання, bashне виправлене чи що-небудь (принаймні для цього). Емулятор терміналу за замовчуванням запускає оболонки входу за замовчуванням, і, імовірно, iTerm копіює це.


1
+1 для згадування tcsh, оскільки його поведінка набагато безпечніше в цьому відношенні, ніж поведінка bash: коли запускається як інтерактивна оболонка для входу, tcsh джерела обох .profile і .tcshrc/ .cshrcне вимагаючи жодних клубів, як той, який я дав у своїй відповіді. Враховуючи це, я підозрюю, що така поведінка є нефіксованою регресією, викликаною переходом від tcsh на bash.
Ільмарі Каронен

@IlmariKaronen Ви маєте на увазі (тут і там ), що джерела tcsh .loginта .tcshrc/ .cshrc? Не було б сенсу tcsh до джерела .profile; зазвичай він містить команди з shсинтаксисом, які tcshне приймаються. У мене немає macOS, але я створив /bin/tcshсвою оболонку для входу на Ubuntu 16.04. .profileне є джерелом. tcsh (1) не згадує цей файл, а також цей tcsh (1) .
Елія Каган

3

Це оновлення поточного статусу: відповіді стали неодноразовими, оскільки випущено нові версії MacOSX та змінилася поведінка входу.

Це питання було задано і відповіли у 2014 році. Я досліджував цю тему, намагаючись створити загальний набір .bashrc & .bash_profile, який використовується для різних дистрибутивів Linux та BSD (як би вони їх не називали, якщо вони не дистрибутивами).

Нещодавно я купив вживаний Mac Mini із встановленою Sierra, тому тепер у мене є системи з 10.6, 10.10, 10.11 та 10.12. Хоча я заглушив старіші (залишивши підказки до їх попереднього статусу), установка Sierra 10.12 не стосується.

Результати: У 10.12 Sierra за замовчуванням не створено .bashrc, .bash_profile або .profile. У / etc є bashrc, bashrc_Apple_Terminal та профіль. Зміст / тощо / профілю:

# System-wide .profile for sh(1)

if [ -x /usr/libexec/path_helper ]; then
    eval `/usr/libexec/path_helper -s`
fi

if [ "${BASH-no}" != "no" ]; then
    [ -r /etc/bashrc ] && . /etc/bashrc
fi

Зміст / etc / bashrc:

# System-wide .bashrc file for interactive bash(1) shells.
if [ -z "$PS1" ]; then
   return
fi

PS1='\h:\W \u\$ '
# Make bash check its window size after a process completes
shopt -s checkwinsize

[ -r "/etc/bashrc_$TERM_PROGRAM" ] && . "/etc/bashrc_$TERM_PROGRAM"

Сценарій / etc / bashrc_Apple_Terminal встановлює змінну PROMPT_COMMAND і встановлює механізм збереження стану сеансу для кожного терміналу; якщо термінальна програма закрита, стан попереднього сеансу відновлюється при повторному запуску програми. В іншому випадку майже нічого (мінімальний $ PS1) не встановлюється в / etc / bashrc, не залишаючи будь-якої іншої настройки (реального $ PS1, псевдонімів, функцій) встановлювати в налаштуваннях ~ / .bashrc та $ PATH у .bash_profile (або в .profile , створений у .bash_profile).

Я підтвердив, що iTerm2 поводиться так само, як і додаток Terminal, за винятком того, що поведінка за замовчуванням при запуску сеансу входу є видимою і її можна редагувати.

Якщо ви запустите термінальний сеанс X11 (тепер XQuartz) XTerm, ви побачите сеанс без входу, такий самий, як у системі Linux; .bash_profile (або .profile) пропускається, і ви просто отримаєте .bashrc.

І ось моя відповідь:

Хоча додаток Terminal претендує на xterm (TERM = xterm-256color), він не встановлює змінну $ DISPLAY, якщо не встановлено X11. Ми спостерігаємо моделювання середовища X, але не зовсім реального. Якщо ви запустили SSH в іншу систему з перемикачем -X (увімкніть пересилання X11), вона вийде з ладу, оскільки немає змінної $ DISPLAY. Якщо ви встановили X11, то SSH в іншу систему, переадресація X11 буде успішною.

Підсумок (і коротка відповідь): Додаток Terminal не є справжнім терміналом X11 (не встановлює $ DISPLAY); він поводиться набагато більше, як вхід в SSH, ніж сеанс XTerm, оскільки він повинен бути сеансом входу для встановлення значень з / etc / profile та ~ / .bash_profile або ~ / .profile


0

Відповіді вище пояснювали причину того, чому інтерактивні оболонки - це оболонки для входу в macOS за замовчуванням: налаштування в /etc/profile, ~/.profileуспадковується оболонкою без входу в системах на базі X, але не на macOS . Тут я хочу нагадати, що ви завжди повинні використовувати оболонку входу на macOS через існування path_helper:

 cat /etc/profile # or cat /etc/zprofile
# System-wide .profile for sh(1)

if [ -x /usr/libexec/path_helper ]; then
    eval `/usr/libexec/path_helper -s`
fi

if [ "${BASH-no}" != "no" ]; then
    [ -r /etc/bashrc ] && . /etc/bashrc
fi

path_helperУтиліта зчитує вміст файлів в каталогах , /etc/paths.dі /etc/manpaths.d та додає їх вміст в PATHі MANPATHзмінних оточення відповідно. ( MANPATHЗмінна навколишнього середовища не буде змінена, якщо вона вже не встановлена ​​в середовищі.)

Якщо ви використовуєте оболонку без входу, деякі шляхи не буде імпортовано.

Я думаю , що це завжди гарна ідея для розробників , щоб помістити файл в /etc/paths.dімпортувати їх значення шляху, але не симлінк відзивної виконавчі файли в таких місцях , як /usr/binабо /bin. (За замовчуванням PATHце /usr/bin:/bin:/usr/sbin:/sbin. Не кожен використовує Homebrew або MacPorts додавання користувацьких значень в PATH. Так що не завжди безпечне місце , щоб поставити симлінк ЇХ команд.)

Ось приклад файлів у /etc/paths.d. В основному ви вводите одне значення кожного рядка.

 cat /etc/paths.d/Wireshark
/Applications/Wireshark.app/Contents/MacOS

Довідка:

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