Di Linux dan, setahu saya, semua sistem Unix, emulator terminal menjalankan shell interaktif, non-login secara default. Ini berarti bahwa, untuk bash, shell yang dimulai akan:
Ketika shell interaktif yang bukan shell login dimulai, bash membaca dan mengeksekusi perintah dari
/etc/bash.bashrc
dan~/.bashrc
, jika file-file ini ada. Ini dapat dihambat dengan menggunakan--norc
opsi.The
--rcfile
pilihan file akan memaksa bash untuk membaca dan menjalankan perintah dari file bukan/etc/bash.bashrc
dan~/.bashrc
.
Dan untuk shell login:
Ketika bash dipanggil sebagai shell login interaktif, atau sebagai shell non-interaktif dengan
--login
opsi, bash pertama kali membaca dan mengeksekusi perintah dari file/etc/profile
, jika file itu ada. Setelah membaca file itu, tampaknya untuk~/.bash_profile
,~/.bash_login
dan~/.profile
, agar, dan membaca dan mengeksekusi perintah dari yang pertama yang ada dan dapat dibaca.The
--noprofile
pilihan mungkin digunakan ketika shell dimulai untuk menghambat perilaku ini.
Pada OSX, bagaimanapun, shell default (yang bash) dimulai di terminal default (Terminal.app) sebenarnya sumber ~/.bash_profile
atau lainnya ~.profile
. Dengan kata lain, ini bertindak seperti shell login.
Pertanyaan utama : Mengapa shell interaktif interaktif merupakan shell login pada OSX? Mengapa OSX memilih untuk melakukan ini? Ini berarti bahwa semua instruksi / tutorial untuk hal-hal berbasis shell yang menyebutkan mengubah hal-hal di ~/.bashrc
akan gagal pada OSX atau sebaliknya ~/.profile
. Tetap saja, sementara banyak tuduhan dapat diajukan ke Apple, mempekerjakan devs yang tidak kompeten atau idiot bukanlah salah satunya. Agaknya, mereka punya alasan bagus untuk ini, jadi mengapa?
Subquestions: Apakah Terminal.app benar-benar menjalankan shell login interaktif atau apakah mereka mengubah perilaku bash? Apakah ini khusus untuk Terminal.app atau independen terhadap terminal emulator?
Jawaban:
Cara kerjanya seharusnya adalah, pada titik ketika Anda mendapatkan prompt shell, keduanya
.profile
dan.bashrc
telah dijalankan. Detail spesifik tentang cara Anda sampai pada titik itu memiliki relevansi sekunder, tetapi jika salah satu file tidak dijalankan sama sekali, Anda akan memiliki shell dengan pengaturan yang tidak lengkap.Alasan terminal emulator di Linux (dan sistem berbasis X lainnya) tidak perlu menjalankan
.profile
sendiri adalah bahwa hal itu biasanya sudah berjalan ketika Anda masuk ke X. Pengaturan di.profile
seharusnya dari jenis yang dapat diwarisi oleh subproses, jadi selama itu dieksekusi sekali ketika Anda masuk (misalnya melalui.Xsession
), subkulit lebih lanjut tidak perlu menjalankannya kembali.Seperti yang dijelaskan laman wiki Debian oleh Alan Shutko:
Semua aturan yang sama berlaku pada OSX, juga, kecuali untuk satu hal - GUI OSX tidak berjalan
.profile
ketika Anda masuk, tampaknya karena ia memiliki metode sendiri memuat pengaturan global. Tapi itu berarti bahwa terminal emulator di OSX tidak perlu dijalankan.profile
(dengan mengatakan shell itu meluncurkan bahwa itu adalah shell login), jika tidak, anda akan berakhir dengan shell berpotensi lumpuh.Sekarang, semacam kekhasan bash, tidak dibagikan oleh kebanyakan shell lain, adalah bahwa itu tidak akan berjalan secara otomatis
.bashrc
jika dimulai sebagai shell login. Cara kerja standar untuk itu adalah memasukkan sesuatu seperti perintah berikut ini di.bash_profile
:Atau, mungkin tidak ada
.bash_profile
sama sekali, dan cukup sertakan beberapa kode spesifik-bash dalam.profile
file generik untuk dijalankan.bashrc
jika diperlukan.Jika OSX default
.bash_profile
atau.profile
tidak melakukan ini, maka itu bisa dibilang bug. Bagaimanapun, penyelesaian yang tepat adalah dengan hanya menambahkan garis-garis itu.bash_profile
.Sunting: Seperti strugee note , shell default pada OSX dulu tcsh, yang perilakunya lebih waras dalam hal ini: ketika dijalankan sebagai shell login interaktif, tcsh secara otomatis membaca keduanya
.profile
dan.tcshrc
/.cshrc
, dan dengan demikian tidak memerlukan solusi seperti.bash_profile
trik. ditunjukkan di atas.Berdasarkan hal ini, saya yakin 99% bahwa kegagalan OSX untuk memasok default yang sesuai
.bash_profile
adalah karena, ketika mereka beralih dari tcsh ke bash, orang-orang di Apple tidak memperhatikan kutil kecil ini dalam perilaku startup bash. Dengan tcsh, tidak ada trik seperti itu diperlukan - mulai tcsh sebagai shell login dari emulator terminal OSX Just Plain Works dan melakukan hal yang benar tanpa kluges seperti itu.sumber
.bashrc
tidak relevan? Mengapa mereka memilih untuk membuat semua shell login shell? Sejauh yang saya tahu, hanya kalimat terakhir Anda yang membahasnya dan hanya mengatakan itu bug..profile
ketika pengguna masuk ke GUI, jadi mereka harus mengeksekusinya nanti untuk mendapatkan variabel lingkungan seperti$PATH
, yang biasanya diatur dalam.profile
, dikonfigurasi dengan benar . Fakta bahwa, sebagai efek samping, ini menyebabkan.bashrc
tidak bersumber adalah bug; Anda bisa berdebat apakah bug di bash atau di OSX, tapi itu tidak mengubah fakta bahwa perilaku yang benar adalah untuk memastikan bahwa kedua variabel lingkungan dari.profile
dan pengaturan konfigurasi bash dari.bashrc
dimuat..bashrc
sumber.profile
akan menjadi ide yang buruk, karena itu akan menyebabkan setiap subkulit dijalankan kembali.profile
. Jika tidak ada yang lain, ini akan menyebabkan.profile
idiom umum inginexport PATH = "$HOME/bin:$PATH"
terus entri yang berlebihan$PATH
. Memiliki.profile
sumber.bashrc
jauh lebih masuk akal, tetapi hanya setelah memeriksa bahwa shell itu berjalan di bawah, pada kenyataannya, bash. Memiliki.bash_profile
sumber keduanya.profile
dan.bashrc
, seperti yang saya sarankan di atas, adalah, IMO, opsi yang paling masuk akal..profile
", sedangkan jawaban untuk "mengapa mereka tidak mengambil.bashrc
dari.profile
, lalu?" adalah "karena itu bug!" Serius, itu tidak mungkin menjadi keputusan yang disengaja; itu hanya sesuatu yang mereka abaikan, mungkin karena, dalam ekosistem Mac, kerang adalah warga negara kelas dua yang seharusnya tidak ditangani oleh sebagian besar pengguna. (Mz. Lihat juga jawaban orang asing untuk penjelasan historis; hampir pasti ini adalah regresi dari pergantian dari tcsh ke bash.)Alasan utama bahwa aplikasi terminal X menjalankan shell non-login secara default adalah bahwa di awal waktu, .Xsession Anda akan menjalankan .profile untuk mengatur item login awal Anda. Kemudian, karena semua sudah diatur, aplikasi terminal tidak perlu menjalankannya, mereka dapat menjalankan .bashrc. Diskusi mengapa ini penting adalah di https://wiki.debian.org/DotFiles :
Pada OS X, lingkungan pengguna tidak dimulai oleh setumpuk skrip shell, dan launchd tidak sumber .profile kapan saja. (Itu agak memalukan, karena itu berarti jauh lebih menyebalkan untuk mengatur variabel lingkungan, tetapi begitulah hidup.) Karena tidak, kapan akan berjalan. Profil? Hanya jika Anda masuk? Sepertinya tidak ada gunanya, karena banyak kotak tidak akan pernah menjadi target ssh. Mungkin juga membuat terminal menjalankan shell login secara default, sehingga. Profil akan dijalankan kapan-kapan.
Bagaimana dengan .bashrc? Apakah itu tidak berguna? Tidak. Masih memiliki tujuan yang dimilikinya pada zaman VT100. Ini digunakan kapan saja Anda membuka shell selain membuka jendela Terminal. Jadi jika Anda keluar dari Emacs atau vi, atau jika Anda melakukan pengguna su.
sumber
.profile
sumber Debian.bashrc
, bukan mengapa OSX memutuskan untuk membuat semua shell login shell secara default. Sebenarnya, Anda menjawab pertanyaan saya yang lain , dan terima kasih! Namun, jawaban Anda tidak menjelaskan pilihan OSX dan kutipan Debian sama sekali tidak relevan di sini sejauh yang saya tahu (tolong beri tahu saya jika saya tidak mengerti intinya). Cara OSX membuat.bashrc
dll tidak berguna dan tidak membuat.profile
lebih berguna.Saya tidak tahu mengapa mereka melakukan itu. Namun, ini tebakan saya.
Untuk mulai dengan, perlu dicatat bahwa pada sistem GNU / Linux, Anda tentu saja dapat beralih ke vt1, vt2, dll. Anda mendapatkan shell login di sana. Pada sistem OS X, tidak ada yang setara. Satu-satunya cara untuk mengakses dasar-dasar UNIX adalah melalui terminal emulator atau melalui mode pengguna tunggal (penafian: Saya tidak pernah benar-benar menggunakan mode pengguna tunggal; itu adalah IIRC yang digerakkan oleh perintah tapi saya mungkin salah). Oleh karena itu, di OS X apa pun defaultnya di emulator adalah default untuk seluruh sistem.
Sekarang, mengapa Anda membuat default shell login? Ada beberapa (baca: tidak banyak) alasan yang bisa saya pikirkan untuk melakukan ini.
tcsh
. Ini adalah tebakan liar yang bisa Anda peroleh, tetapi mungkin hal itutcsh
biasanya dilakukan ketika dijalankan sebagai shell login, dan pola historisnya macet. (Tapi saya ragu - mungkin salah satu pelanggan tetap bisa memberi tahu kami.)Jujur, saya sudah menggunakan Darwin selama ~ 6 tahun dan saya tidak bisa menjawab pertanyaan ini dengan benar. Itu juga tidak masuk akal bagi saya.
Untuk menjawab pertanyaan Anda,
bash
jangan ditambal atau apa pun (setidaknya untuk ini). Emulator terminal default menjalankan shell login secara default, dan mungkin iTerm menyalinnya.sumber
.profile
dan.tcshrc
/.cshrc
tanpa memerlukan klasp seperti yang saya berikan dalam jawaban saya. Mengingat itu, saya menduga perilaku ini adalah regresi tidak tetap yang disebabkan oleh peralihan dari tcsh ke bash..login
dan.tcshrc
/.cshrc
? Tidak masuk akal bagi tcsh untuk sumber.profile
; biasanya berisi perintah dengansh
sintaks yangtcsh
tidak akan menerima. Saya tidak punya macOS tapi saya membuat/bin/tcsh
shell login saya di Ubuntu 16.04..profile
tidak bersumber. tcsh (1) tidak menyebutkan file itu, juga tcsh ini (1) .Ini adalah pembaruan untuk status saat ini: jawaban menjadi basi karena versi MacOSX baru telah dirilis dan perilaku login telah berubah.
Pertanyaan ini ditanyakan dan dijawab pada tahun 2014. Saya telah meneliti subjek ini dalam upaya untuk membangun set .bashrc & .bash_profile yang umum digunakan di berbagai distro Linux dan BSD (apa pun namanya jika tidak distro).
Saya baru-baru ini membeli Mac Mini bekas dengan Sierra diinstal, jadi saya sekarang memiliki sistem dengan 10.6, 10.10, 10.11, dan 10.12. Meskipun saya telah membuat yang lebih tua (meninggalkan petunjuk ke status sebelumnya), instalasi 10.12 Sierra tidak tersentuh.
Hasil: Di 10.12 Sierra, tidak ada .bashrc, .bash_profile, atau .profile default yang dibuat. Di / etc, ada bashrc, bashrc_Apple_Terminal, dan profil. Isi dari / etc / profile:
Isi dari / etc / bashrc:
Skrip / etc / bashrc_Apple_Terminal menetapkan variabel PROMPT_COMMAND dan membuat mekanisme untuk mempertahankan status sesi untuk setiap terminal; jika aplikasi terminal berhenti, status sesi sebelumnya dipulihkan ketika aplikasi dimulai lagi. Kalau tidak, hampir tidak ada (minimal $ PS1) yang diatur di / etc / bashrc, meninggalkan kustomisasi lain (real $ PS1, alias, fungsi) yang akan diset dalam ~ / .bashrc dan $ PATH pengaturan di .bash_profile (atau dalam .profile , bersumber dari .bash_profile).
Saya telah mengkonfirmasi bahwa iTerm2 berperilaku sama dengan aplikasi Terminal, kecuali bahwa perilaku default memulai sesi login terlihat dan dapat diedit.
Jika Anda menjalankan sesi terminal XTerm X11 (sekarang XQuartz), Anda akan melihat sesi non-login, sama seperti pada sistem Linux; .bash_profile (atau .profile) dilewati, dan Anda hanya mendapatkan .bashrc.
Dan inilah jawaban saya:
Meskipun aplikasi Terminal mengklaim sebagai xterm (TERM = xterm-256color), itu tidak menetapkan variabel $ DISPLAY kecuali X11 diinstal. Kami melihat simulasi lingkungan X, tetapi tidak sepenuhnya nyata. Jika Anda SSH ke sistem lain dengan -X switch (aktifkan penerusan X11), itu akan gagal karena tidak ada variabel $ DISPLAY. Jika Anda telah menginstal X11, maka SSH ke sistem lain, penerusan X11 akan berhasil.
Intinya (dan jawaban singkat): Aplikasi Terminal bukan terminal X11 sejati (tidak menyetel $ DISPLAY); itu berperilaku lebih seperti login SSH daripada sesi XTerm, dalam hal itu harus menjadi sesi login untuk menetapkan nilai dari / etc / profile dan ~ / .bash_profile atau ~ / .profile
sumber
Jawaban di atas menjelaskan alasan mengapa shell interaktif adalah shell login pada macOS secara default: setting in
/etc/profile
,~/.profile
diwarisi oleh shell non-login pada sistem berbasis X, tetapi tidak pada macOS . Di sini saya ingin mengingatkan Anda bahwa Anda harus selalu menggunakan shell login di macOS karena keberadaanpath_helper
:Jika Anda menggunakan shell non-login, beberapa jalur tidak akan diimpor.
Saya pikir itu selalu merupakan ide yang baik bagi pengembang untuk memasukkan file ke dalam
/etc/paths.d
untuk mengimpor nilai path mereka, tetapi tidak untuk symlink biner yang dapat dipanggil ke lokasi seperti/usr/bin
atau/bin
. (DefaultnyaPATH
adalah/usr/bin:/bin:/usr/sbin:/sbin
. Tidak semua orang menggunakan Homebrew atau MacPorts untuk menambahkan nilai khususPATH
. Jadi tidak selalu ada tempat yang aman untuk menaruh symlink dari perintah yang bisa dipanggil.)Berikut adalah contoh file di
/etc/paths.d
. Pada dasarnya Anda menempatkan satu nilai setiap baris.Referensi:
man path_helper
sumber