OSX giriş kabukları üzerindeki etkileşimli kabukları neden varsayılan olarak?


43

Linux'ta ve bildiğim kadarıyla, tüm Unix sistemleri, terminal emülatörleri, varsayılan olarak etkileşimli, giriş yapmayan kabuklar çalıştırıyor. Bu, bash için başlatılan kabuğun:

Oturum açma kabuğu olmayan etkileşimli bir kabuk başlatıldığında, bash komutları okur ve bunları çalıştırır /etc/bash.bashrcve ~/.bashrcbu dosyalar varsa. Bu --norc seçenek kullanılarak engellenebilir .

--rcfile Dosya seçeneği okuyup yerine dosyadan komutları yürütmek için bash zorlar /etc/bash.bashrcve ~/.bashrc.

Ve giriş kabukları için:

Bash etkileşimli bir giriş kabuğu veya --loginseçenekle etkileşimli olmayan bir kabuk olarak çağrıldığında , ilk önce dosyadan komutları okur ve yürütür /etc/profile, eğer o dosya varsa. Bu dosyayı okuduktan sonra, arar ~/.bash_profile, ~/.bash_loginve ~/.profile, bu sırayla ve okur ve var ve okunabilir olanlarını gelen yürütür komutları.

--noprofileKabuk bu davranışı engellemek için başlatıldığında seçenek kullanılan olabilir.

Bununla birlikte, OSX’te, varsayılan terminal (bash), varsayılan terminalde (Terminal.app) fiilen kaynak ~/.bash_profileveya ~.profilevb. Başlatılır. Diğer bir deyişle, bir giriş kabuğu gibi davranır.

Ana soru : Varsayılan etkileşimli kabuk neden OSX'te bir giriş kabuğu? OSX neden bunu yapmayı seçti? Bu, kabuk değiştiren şeylerle ilgili tüm talimatların / öğreticilerin, değiştirilen şeylerden bahseden ~/.bashrcOSX'te başarısız olacağı veya bunun tersi anlamına gelir ~/.profile. Yine de, birçok suçlama Apple'da seviyelendirilebilir olsa da, beceriksiz veya aptalca şeytanları işe almak bunlardan biri değildir. Muhtemelen, bunun için iyi bir nedenleri vardı, öyleyse neden?

Subquestions: Terminal.app aslında etkileşimli bir giriş kabuğu çalıştırıyor mu veya bash'ın davranışını değiştirdi mi? Bu Terminal.app'a özgü mü yoksa terminal emülatöründen bağımsız mı?


2
Terminal.app bir giriş kabuğu çalıştırır. Apple'ın neden bunu seçtiğini bilmiyorum.
Gilles 'SO- kötülük' dur

Yanıtlar:


33

O çıkmanın yolu sözde bir kabuk istemi olsun, hem zaman işi noktada, yani .profileve .bashrcbeen çalıştırmak. Bu noktaya nasıl ulaştığınıza dair özel detaylar ikincil alaka düzeyindeydi, ancak dosyalardan herhangi biri hiç çalıştırılmadıysa, tamamlanmamış ayarlara sahip bir kabuğunuz olacaktı.

Linux'taki terminal emülatörlerinin (ve diğer X tabanlı sistemlerdeki) kendilerini çalıştırmaya gerek duymamalarının nedeni .profile, normalde X'e giriş yaptığınızda zaten çalıştırılmış olmanızdır. Buradaki ayarların .profileyapılabilecek türden olması gerekir. Alt işlemler tarafından devralındığı için, oturum açtığınızda bir kez yürütüldüğü sürece (örneğin, üzerinden .Xsession), başka alt kabukların yeniden çalıştırılması gerekmez.

As Debian wiki sayfası Alan Shutko ile bağlantılı açıklıyor:

"Neden .bashrcayrı bir dosya .bash_profilekomutları işleniyor. Peki? Bu makineler son derece yavaş bugünün iş istasyonlarına karşılaştırıldı çoğunlukla tarihsel nedenlerle yapılır .profileveya .bash_profileözellikle bir makinede, oldukça uzun zaman alabilir nerede bir sürü iş harici komutlar tarafından yapılması gerekiyordu (bash öncesi), bu yüzden alt süreçlere aktarılabilecek çevre değişkenleri yaratan zor başlangıç ​​ayar komutları .bash_profilegirildi. Miras alınmayan geçici ayarlar ve takma adlar verildi. içinde .bashrcböylece olabileceğini her alt kabuğa göre yeniden okuyun."

Aynı kurallar, bir şey dışında OSX'te de geçerlidir - .profilegörünüşte, genel ayarları yüklemek için kendi yöntemine sahip olduğu için OSX GUI giriş yaptığınızda çalışmaz . Ama araçlar OSX üzerinde bir terminal emülatörü o yapar vadede ihtiyacını .profile(bir giriş kabuğu olduğunu Kabuğu o başlattı anlatarak), aksi takdirde potansiyel olarak sakat kabuğu ile bitirmek istiyorum.


Şimdi, diğer kabukların çoğu tarafından paylaşılmayan bir tür saçma sapma türü, .bashrcbir giriş kabuğu olarak başlatıldığında otomatik olarak çalışmayacak olmasıdır. Bunun için standart çözüm, aşağıdaki komutlara benzer bir şey eklemektir .bash_profile:

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

Alternatif olarak, hiçbirine sahip olmamak mümkündür .bash_profileve eğer gerekliyse .profileçalıştırmak için genel dosyaya bazı bash-özgü kodları dahil .bashrcetmek mümkündür.

OSX varsayılan ise .bash_profileveya .profile bunu yapmazsa , bu muhtemelen bir hata. Her durumda, uygun çözüm, bu satırları basitçe eklemektir .bash_profile.


Düzenleme: Strugee'nin belirttiği gibi , OSX'teki varsayılan kabuk tcsh'dı , davranışları bu açıdan daha dikkatliydi: etkileşimli bir giriş kabuğu olarak çalıştırıldığında, tcsh otomatik olarak hem .profile ve .tcshrc / veya hem okur hem .cshrcde .bash_profilehile gibi herhangi bir geçici çözüme ihtiyaç duymaz Yukarıda verilen.

Buna dayanarak, OSX'in uygun bir temerrüde düşmemesinin% 99 eminim .bash_profile, çünkü tcsh'den bash'a geçtiklerinde, Apple'daki insanlar bash'ın başlangıç ​​davranışında bu küçük siğil fark etmediler. Tcsh ile böyle bir hileye gerek yoktu - tcsh'i bir OSX terminal emülatöründen bir giriş kabuğu olarak başlatarak Just Plain Works ve böyle bir ipucu olmadan doğru olanı yapıyor.


1
Teşekkürler, hepsini biliyordum. Sorum şu: OSX neden.bashrc alakasız hale getirecek şekilde ayarlamayı seçti ? Neden tüm kabukları giriş kabukları yapmayı seçtiler? Söyleyebileceğim kadarıyla, sadece son cümleniz bu adrese hitap ediyor ve bunun bir hata olduğunu söylüyor.
terdon

1
Hayır, sorun, terminal emülatörlerinde oturum açma kabukları başlatmalarıdır. Dotfiles varsayılan bash davranışıdır, oturum açma kabukları başlayarak bashrc vb. Bilgileri okuyacaktır. Oturum açma kabukları oturum açmayanlar yerine neden çalıştırıldığı sorusudur.
terdon

2
Evet, hem ben hem de Alan, Linux'un aksine .profile, kullanıcı GUI'ye giriş yaptığında OSX'in çalışmamasını , dolayısıyla daha sonra $PATHnormalde ayarlanmış, gibi ayarlanmış ortam değişkenlerini .profiledoğru şekilde yapılandırmak için çalıştırmaları gerektiğini açıkladı. . Bunun bir yan etki .bashrcolarak kaynaklanmamasına neden olması bir hatadır; bash veya OSX'te bir hata olup olmadığını tartışabilirsiniz, ancak bu doğru davranışın hem ortam değişkenlerinin hem .profilede bash config ayarının .bashrcyüklendiğinden emin olmak olacağını değiştirmez .
Ilmari Karonen

1
.bashrcKaynağa sahip .profileolmak kötü bir fikir olurdu, çünkü her deniz kabuğunun yeniden çalışmasına neden olur .profile. Başka bir şey değilse, bu ortak .profiledeyimler export PATH = "$HOME/bin:$PATH"gereksiz girişleri hazırlamaya devam etmek ister $PATH. .profileKaynağa sahip olmak .bashrcçok daha anlamlıdır, ancak yalnızca altında çalışan kabuğun gerçekte bash olduğunu kontrol ettikten sonra. Her .bash_profileikisinin de kaynağına sahip olmak .profile ve .bashrc yukarıda da belirttiğim gibi, en mantıklı seçenek IMO.
Ilmari Karonen

2
Ben de "Neden bir giriş kabuğu kullanıyorlar?" Cevabını söylüyorum. "Onlar yüke ihtiyaç nedeni .profile" ise cevabı "neden olmasın onlar kaynağından, .bashrcgelen .profile, ardından?" ise "bu bir hata çünkü!" Cidden, bu kasıtlı bir karar olamaz; Bu, sadece göz ardı ettikleri bir şeydi, muhtemelen, Mac ekosisteminde, kabukları çoğu kullanıcının uğraşmaması gereken ikinci sınıf vatandaşlar. (Ps. Ayrıca, Strugee'nin tarihsel bir açıklama için verdiği cevaba da bakın ; bu, kesinlikle kesinlikle tcsh'den bash'a geçişin bir gerilemesidir.)
Ilmari Karonen,

14

X terminal uygulamalarının oturum açma kabukları varsayılan olarak çalıştırılmasının ana nedeni, başlangıçta, .Xsession'ın başlangıç ​​oturum açma öğelerini ayarlamak için .profile dosyasını çalıştırmasıydı. Ardından, hepsi zaten kurulduğundan, terminal uygulamalarının onu çalıştırması gerekmedi, .bashrc'yi çalıştırabilirlerdi. Bunun neden önemli olduğunu tartışmak https://wiki.debian.org/DotFiles adresinde :

Örnek olarak xdm alalım. pierre bir gün tatilden geri döndü ve sistem yöneticisinin Debian sistemine xdm kurduğunu keşfetti. Çok iyi oturum açıyor ve xdm .xsession dosyasını okuyor ve fluxbox'ı çalıştırıyor. Yanlış yerel ayarda bir hata mesajı alana kadar her şey yolunda görünüyor! .Bash_profile içindeki LANG değişkenini geçersiz kıldığından ve xdm hiçbir zaman .bash_profile dosyasını okumadığından, LANG değişkeni şimdi fr_CA yerine en_US olarak ayarlanmıştır.

Şimdi, bu sorunun saf çözümü, "xterm" başlatmak yerine, pencere yöneticisini "xterm -ls" başlatmak için yapılandırabilmesidir. Bu bayrak xterm'e normal bir kabuk başlatmak yerine bir giriş kabuğu başlatması gerektiğini söyler. Bu kurulum altında, xterm / bin / bash komutunu gösterir, ancak argüman vektörüne "- / bin / bash" (veya belki de "-bash") koyar, bu nedenle bash bir giriş kabuğu gibi davranır. Bu, her yeni bir xterm açtığında, / etc / profile ve .bash_profile (yerleşik bash davranışı) ve ardından .bashrc (çünkü .bash_profile bunu söylüyor) okur. Bu ilk bakışta iyi görünebilir - nokta dosyaları ağır değil, bu yüzden gecikmeyi fark etmiyor bile - ama daha ince bir sorun var. Ayrıca doğrudan fluxbox menüsünden bir web tarayıcısı başlattı. ve web tarayıcısı, LANG değişkenini şimdi yanlış yerel ayarlara ayarlanmış olan fluxbox'tan devralır. Bu nedenle, xterm'leri iyi olabilir ve xterm'lerinden başlatılan herhangi bir şey iyi olabilirken, web tarayıcısı hala sayfalarını yanlış yerel ayarlarda veriyor.

OS X'te, kullanıcı ortamları bir yığın kabuk betiği tarafından başlatılmaz ve launchd herhangi bir zamanda .profile kaynağını sağlamaz. (Bu utanç verici bir durum çünkü ortam değişkenlerini ayarlamak çok daha can sıkıcı bir durum, ama hayat böyle. Sadece içeri girersen? Bu çok anlamsız görünüyor, çünkü çoğu kutu asla ssh'nin hedefi olmayacak. Terminallerin varsayılan olarak oturum açma kabukları çalıştırmasını sağlayabilir, böylece .profile bir süre çalıştırılabilir.

Peki ya .bashrc? İşe yaramaz mı Hayır. Hala VT100'ün günlerinde olduğu gibi bir amacı var. Terminal penceresini açmaktan başka bir kabuğu açtığınızda kullanılır. Öyleyse Emacs veya vi'den uzak durursanız ya da su kullanıcısıysanız.


1
Alıntı yaptığınız Debian sayfası, OSX'in varsayılan olarak tüm kabukları oturum açma kabukları yapmaya karar vermesinin neden değil, Debian'ın .profilekaynaklarının nedenini açıklar .bashrc. Aslında, benim başka bir soruma cevap veriyorsunuz ve teşekkürler! Ancak, cevabınız OSX seçimini açıklamıyor ve Debian teklifi burada söyleyebileceğim kadarıyla tamamen alakasız (lütfen sadece noktayı kaçırıyorsam bana bildirin). OSX yolu .bashrcvb işe yaramaz hale getirir ve .profiledaha fazla kullanışlı yapmaz .
terdon

4

Bunu neden yaptıklarını bilmiyorum. Ancak, işte benim tahminim.

Başlamak için, GNU / Linux sisteminde elbette vt1, vt2 vb. Seçeneklerine geçiş yapabileceğinize değinmeye değer. Bir OS X sisteminde, eşdeğeri yoktur. UNIX desteklerine erişmenin tek yolu bir terminal emülatörü veya tek kullanıcı modudur (feragatname: Aslında tek kullanıcı modunu hiç kullanmamıştım; komut satırıyla çalışan IIRC ama hatalı olabilirim). Bu nedenle, OS X'te emülatörde varsayılan değer ne olursa olsun, tüm sistem için varsayılan değerdir.

Şimdi, neden varsayılanı bir giriş kabuğu yapmalısınız? Bunu yapmayı düşünebilmemin birkaç nedeni (okundu: çok değil) var.

  • Kutuya SSH koysanız tutarlı bir kullanıcı deneyimi sağlar. (Özellikle OS X'in sunucu sürümü için önemlidir - büyük olasılıkla bir OS X sunucusu kullanıyorsanız, acemisiniz.)
  • OS X'in varsayılan kabuğu eskiden tcsh. Bu tahmin edebileceğiniz kadar vahşi bir tahminle ilgili, ancak tcshnormalde bir giriş kabuğu olarak çalıştırıldığında bir şey yapmış olabilir ve tarihsel kalıp sıkışmış olabilir. (Şüpheliyim, yine de - belki de eski normallerden biri bize söyleyebilir.)
  • “Biz Apple'ız. Gezegendeki en büyük UNIX dağıtımının satıcılarıyız. Sebeplerimizin ne kadar önemsiz olduğu önemli değil; eğer bir karar verirsek, aracınız bununla başa çıkmalı”.

Dürüst olmak gerekirse, ~ 6 yıldır Darwin kullanıyorum ve bu soruya doğru cevap veremiyorum. Bana da hiç mantıklı gelmiyor.

Aldığınız soruyu cevaplamak için, bashyamalı ya da hiçbir şey değil (en azından bunun için). Varsayılan terminal emülatörü varsayılan olarak oturum açma kabukları çalıştırır ve muhtemelen iTerm bunu kopyalar.


1
Tcsh'dan bahsettiği için +1, çünkü davranışı bu konuda bash'den çok daha mantıklıdır : etkileşimli bir giriş kabuğu olarak başladığında, tcsh kaynakları hem de .profile ve .tcshrc/ / .cshrccevabımda verdiğim gibi herhangi bir kluj gerektirmeden kaynaklamaktadır . Buna göre, bu davranışın tcsh'den bash'a geçişten kaynaklanan sabit olmayan bir regresyon olduğundan şüpheleniyorum.
Ilmari Karonen

@IlmariKaronen Eğer (burada ve ortalama Do orada ) tcsh kaynaklarına olduğunu .loginve .tcshrc/ .cshrc? Tcsh'ın kaynak yapması bir anlam ifade etmeyecektir .profile; genellikle kabul etmeyen shsözdizimine sahip komutları içerir tcsh. MacOS'um yok ama /bin/tcshgiriş kabuğumu Ubuntu 16.04 ile yaptım . .profilekaynaklı değil. tcsh (1) bu dosyadan bahsetmiyor, ne de tcsh (1) .
Eliah Kagan 17:17

3

Bu mevcut durum için bir güncellemedir: yeni MacOSX sürümleri piyasaya sürüldüğünde ve oturum açma davranışı değiştikçe yanıtlar bayatladı.

Bu soru 2014'te soruldu ve cevaplandı. Konuyu, farklı Linux dağıtımları ve BSD (dağıtım yapmazlarsa, ne diyorlarsa) kullanmak üzere ayarlanmış ortak bir .bashrc & .bash_profile oluşturmak amacıyla araştırıyorum.

Geçenlerde Sierra yüklü bir kullanılmış Mini Mac aldım, bu yüzden şimdi 10.6, 10.10, 10.11 ve 10.12 sistemlerine sahibim. Her ne kadar eskileri mungsa da (ipuçlarını önceki durumlarına bırakarak), 10.12 Sierra kurulumuna dokunulmadı.

Sonuçlar: 10.12 Sierra'da, varsayılan NO .bashrc, .bash_profile veya .profile oluşturuldu. / Etc içinde bashrc, bashrc_Apple_Terminal ve profil var. / Etc / profile içeriği:

# 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 içeriği:

# 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 betiği PROMPT_COMMAND değişkenini ayarlar ve her bir terminal için oturum durumunu korumak için bir mekanizma kurar; Terminal uygulaması sonlandırılırsa, uygulama tekrar başlatıldığında önceki oturumun durumu geri yüklenir. Aksi halde, / etc / bashrc içinde hemen hemen hiçbir şey (minimum $ PS1) kurulmaz ve / b. , kaynak tarafından .bash_profile).

İTerm2'nin Terminal uygulaması ile aynı şekilde davrandığını onayladım, ancak oturum açma oturumunu başlatma varsayılan davranışı görünür ve düzenlenebilir.

Bir X11 (şimdi XQuartz) XTerm terminal oturumunu çalıştırırsanız, Linux sistemindeki gibi oturum açmayan bir oturum görürsünüz; .bash_profile (veya .profile) atlanır ve sadece .bashrc alırsınız.

Ve işte cevabım:

Terminal uygulaması bir xterm (TERM = xterm-256color) olduğunu iddia etse de, X11 yüklenmediği sürece $ DISPLAY değişkenini ayarlamaz. Bir X ortamının simülasyonunu görüyoruz, ancak tamamen gerçek değil. -X anahtarlı (X11 yönlendirmeyi etkinleştir) etkin bir sistemde SSH kullanırsanız, $ DISPLAY değişkeni olmadığından başarısız olur. X11'i ve ardından SSH'yi başka bir sisteme yüklediyseniz, X11 iletimi başarılı olur.

Alt satır (ve kısa cevap): Terminal uygulaması gerçek bir X11 terminali değildir ($ DISPLAY ayarlamaz); / etc / profile ve ~ / .bash_profile veya ~ / .profile öğelerini ayarlamak için bir oturum açma oturumu olması gerektiğinden, bir XTerm oturumundan çok bir SSH oturumu gibi davranır.


0

: Cevaplar yukarıdaki interaktif kabukları giriş varsayılan olarak MacOS kabuklarını neden nedeni açıkladı ayarları /etc/profile, ~/.profileancak MacOS üzerinde X tabanlı sistemlerde olmayan bir giriş kabuğu tarafından devralınan . İşte size hatırlatmak isterim ki , var olmasından dolayı her zaman macOS'ta login kabuğu kullanmalısınızpath_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_helperYarar dizinleri dosyaların içeriğini okur /etc/paths.dve /etc/manpaths.d ve onların içeriklerini ekler PATHve MANPATHsırasıyla ortam değişkenleri. (Ortam MANPATHdeğişkeni, daha önce çevrede ayarlanmadıkça değiştirilmeyecektir.)

Giriş yapmayan bir kabuk kullanıyorsanız, bazı yollar alınmaz.

Geliştiricinin /etc/paths.dyol değerlerini içe aktarmak için bir dosyaya koymasının her zaman iyi bir fikir olduğunu , ancak çağrılabilir ikili dosyaları /usr/binveya gibi konumlara bağlamanın iyi olmadığını düşünüyorum /bin. (Varsayılan PATHolduğunu /usr/bin:/bin:/usr/sbin:/sbin. Herkes Homebrew veya MacPorts içine özel değerler ekleyerek kullanır PATH. Yani çağrılabilir komutların sembolik koymak için güvenli bir yer her zaman orada değil.)

İşte içindeki dosyalara bir örnek /etc/paths.d. Temel olarak, her satıra bir değer koyuyorsunuz.

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

Referans:

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.