Variabel lingkungan di bash_profile atau bashrc?

36

Saya telah menemukan pertanyaan ini [blog]: Perbedaan antara .bashrc dan .bash_profile sangat berguna tetapi setelah melihat jawaban yang paling banyak dipilih (sangat bagus), saya punya pertanyaan lebih lanjut. Menjelang akhir jawaban yang paling banyak dipilih dan benar saya melihat pernyataan sebagai berikut:

Perhatikan bahwa Anda dapat melihat di sini dan di sana rekomendasi untuk meletakkan definisi variabel lingkungan di ~ / .bashrc atau selalu meluncurkan shell login di terminal. Keduanya adalah ide yang buruk.

  1. Mengapa itu ide yang buruk (saya tidak mencoba untuk bertarung, saya hanya ingin mengerti)?

  2. Jika saya ingin menetapkan variabel lingkungan dan menambahkannya ke PATH (misalnya JAVA_HOME) di mana itu akan menjadi tempat terbaik untuk meletakkan entri ekspor? di ~ / .bash_profile atau ~ / .bashrc ?

  3. Jika jawaban untuk pertanyaan nomor 2 adalah ~ / .bash_profile , maka saya memiliki dua pertanyaan lebih lanjut:

    3.1. Apa yang akan Anda tempatkan di bawah ~ / .bashrc ? hanya alias?

    3.2. Dalam shell non-login, saya percaya ~ / .bash_profile tidak "diambil". Jika ekspor entri JAVA_HOME berada di bash_profile apakah saya dapat menjalankan perintah javac & java ? Apakah akan menemukan mereka di PATH? Apakah itu alasan mengapa beberapa posting dan forum menyarankan pengaturan JAVA_HOME dan sama dengan ~ / .bashrc ?

    Terima kasih sebelumnya.

Viriato
sumber

Jawaban:

26

Pada sistem modern, tidak lazim terjadi kasus yang penting, tetapi itu memang terjadi. (Khususnya, jika Anda menggunakan operasi shell dalam vimbentuk seperti :r !commandatau in-line !<motion>command.)

Apa yang akan Anda tempatkan di bawah ~ / .bashrc? hanya alias?

Anda memasukkan hal-hal ~/.bashrcyang tidak akan diwarisi oleh subkulit secara otomatis; ini berarti alias dan fungsi, sebagian besar, meskipun kadang-kadang Anda memiliki pengaturan variabel yang tidak Anda inginkan terlihat di luar shell (ini sangat jarang). Dapat diperdebatkan bahwa itu harus diekspor entah bagaimana, tetapi berbagai upaya percobaan telah mengalami masalah kompatibilitas dengan mencoba menyembunyikannya di lingkungan dan sebagian besar telah ditinggalkan.

Jika saya ingin menetapkan variabel lingkungan dan menambahkannya ke PATH (misalnya JAVA_HOME) di mana itu akan menjadi tempat terbaik untuk meletakkan entri ekspor? di ~ / .bash_profile atau ~ / .bashrc?

Anda menempatkan pengaturan lingkungan ~/.bash_profilesehingga mereka diberikan pengaturan awal yang waras. Terkadang Anda ingin menimpanya (seringkali ini dilakukan oleh lingkungan yang kompleks seperti Matlab atau Cadence); jika Anda memasukkan pengaturan lingkungan ~/.bashrcmaka shell dijalankan dari dalam lingkungan tersebut akan kehilangan kustomisasi lingkungan, dan hasilnya mungkin tidak berfungsi dengan baik. Ini juga berlaku jika Anda menggunakan paket seperti modul , virtualenv , rvm , dll untuk mengelola beberapa lingkungan pengembangan; memasukkan pengaturan ~/.bashrcAnda berarti Anda tidak dapat menjalankan lingkungan yang Anda inginkan dari dalam editor Anda, tetapi sebaliknya akan dipaksa ke dalam sistem default.

Dalam shell non-login, saya percaya ~ / .bash_profile tidak "diambil".

Ini benar; Anda biasanya ingin shell awal menjadi shell login dan setiap shell dimulai di bawah yang tidak menjadi shell login. Jika shell awal bukan shell login, Anda tidak akan memiliki pengaturan default PATHatau berbagai lainnya (termasuk JAVA_HOMEcontoh Anda ).

Sebagian besar lingkungan desktop diluncurkan dari manajer display (artinya, sebagian besar login grafis) tidak mengatur lingkungan login untuk seluruh desktop, sehingga Anda dipaksa untuk menjalankan shell awal di terminal sebagai shell login. Hal ini menyebabkan sejumlah masalah (terutama bahwa PATHdan semacamnya tersedia untuk program dijalankan dari misalnya panel tidak diatur dengan benar, karena panel bukan terminal dan belum berjalan ~/.bash_profile), tetapi merupakan kompromi yang masuk akal mengingat bahwa itu tidak selalu mungkin untuk berjalan dengan sehat ~/.bash_profiledi lingkungan non-interaktif di awal sesi yang dimulai oleh manajer tampilan, tergantung pada isinya. Terkadang disarankan untuk menempatkan pengaturan lingkungan di~/.bashrcalih-alih mengonfigurasi shell login sebagai gantinya; seperti dibahas di atas, karya ini selama Anda tidak perlu menimpa lingkungan tersebut, dan menyebabkan pecah aneh sekali Anda lakukan perlu untuk melakukannya.

Saya baru-baru ini membantu mendiagnosis masalah seperti ini pada OS X di mana pengguna yang telah menempatkan pengaturan ~/.bashrckemudian mulai menggunakan rvmdan perlbrew melihat perilaku aneh, karena lingkungan yang diatur oleh keduanya "dibatalkan" oleh ~/.bashrceditor dalam dan sudo(yang pada OS X , tidak seperti Linux, menyebarkan pengguna $HOMEsehingga ~/.bashrcdijalankan oleh shell root). Sebelum mencoba menggunakan lingkungan itu, tidak ada masalah; saat mulai menggunakannya, mereka bingung dengan hilangnya pengaturan mereka yang tidak terduga.

geekosaurus
sumber
1
Saya pikir saya mengerti, saya mungkin harus membacanya lebih banyak untuk menginternalisasi lebih banyak tetapi saya menyimpulkan yang berikut. Di lingkungan perusahaan untuk memiliki kontrol yang lebih baik dari shell yang dikustomisasi tanpa efek samping dari global, praktik terbaik adalah menempatkan variabel lingkungan di ~ / .bash_profile . Dalam lingkungan pribadi seperti Ubuntu atau Linux Mint agar PATH diatur dengan benar, saya harus meletakkannya di bawah ~ / .bashrc (atau bahkan di / etc / profile ). Apakah saya benar?
Viriato
Ini kurang berkaitan dengan lingkungan perusahaan daripada dengan apakah Anda hanya pengguna atau pengembang; sistem seperti modulesdan rvmmerupakan alat pengembang, seperti Matlab dan Cadence untuk definisi "pengembang" yang agak berbeda. Pengembangan sederhana juga tidak memerlukan mereka, tetapi ketika Anda perlu uji terhadap beberapa versi Ruby, Perl, atau Python maka Anda benar-benar ingin sesuatu seperti rvm, perlbrew, dan virtualenv(masing-masing) sekitar untuk membantu menjaga semuanya lurus.
geekosaur
2

sejujurnya, ada sedikit perbedaan hari ini terlepas dari apa yang dikatakan guru.

masalah di balik ini adalah bahwa saat ini kami login secara grafis daripada melalui shell login. di masa lalu, kita unix pengguna suka melihat laporan singkat tentang apa yang terjadi di server segera setelah masuk - maka kita akan mulai X dengan baris perintah - laporan ini sering membutuhkan waktu untuk menghasilkan (misalnya 10-20 detik). dan kemudian kita tidak ingin melihat hal yang sama ketika kita mulai misalnya xterm. dengan demikian perbedaannya.

Saat ini saya tidak berpikir perbedaan itu penting sekarang. saya pikir hari ini jika Anda sumber bashrc di bash_profile tidak ada yang bisa menyalahkan Anda.

perhatikan bahwa ini tidak berlaku untuk macos x (setiap terminal.app dimulai adalah shell login)

bubu
sumber
Saya tidak yakin saya sepenuhnya mengerti, tetapi di tempat kerja ketika saya masuk melalui ssh yang merupakan shell login, maka bash_profile dan bashrc bersumber jadi saya kira dalam hal itu tidak masalah. Tetapi jika saya login secara grafis (apa artinya itu)? suka masuk ke ubuntu pribadi saya?
Viriato
Setuju dengan jawaban @bubu di sini - pengaturan apa ~/.bash_profilepun yang tidak memiliki sumber ~/.bashrcagak sulit untuk dikerjakan dan hampir rusak. Aplikasi terminal grafis berarti lebih mudah untuk hanya mencari ~ / .bashrc dan meletakkan semua konfigurasi di sana.
RichVel
1

Nah, tentang "Login Grafis", itu tergantung pada * DM yang Anda gunakan ...

Dengan GDM (Gnome 3.18) saya punya ini:

/ etc / gdm / Xsession

#!/bin/sh   <= *important*

...

# First read /etc/profile and .profile
test -f /etc/profile && . /etc/profile
test -f "$HOME/.profile" && . "$HOME/.profile"
# Second read /etc/xprofile and .xprofile for X specific setup
test -f /etc/xprofile && . /etc/xprofile
test -f "$HOME/.xprofile" && . "$HOME/.xprofile"

Jadi, ~ / .profile didapat dari login menggunakan / bin / sh dan bukan / bin / bash

Ada dua kasus

  1. / bin / sh ditautkan ke / bin / bash tetapi berjalan dalam mode "POSIX / Bourne"
  2. / bin / sh adalah / bin / dash (debian / ubuntu). Tercepat tetapi dengan lebih sedikit fitur (dukungan ShellShock;) )

Jadi profil / bin / sh adalah ~ / .profile dan bukan ~ / .bash_profile, ~ / .zprofile

File ini harus digunakan untuk pengaturan "shell agnostic" , seperti path dan variabel lingkungan.

TIDAK boleh ada program yang dapat dieksekusi untuk interaksi pengguna hanya login kecuali di sini (cek surat, keberuntungan, dll ...)

rc ~ /.* hanya dimaksudkan untuk sesi "interaktif" (alias misalnya ...)

Ada perbedaan antara bash dan zsh untuk shell login interaktif

sumber bash saja .bash_profile, sedangkan sumber zsh dalam urutan:

  1. ~ / .zprofile
  2. ~ / .zshrc
  3. ~ / zlogin (di sini alias yang didefinisikan dalam ~ / .zshrc tersedia. untuk shell "interaktif" + "login"

Cara yang benar untuk melakukan ~ / .bash_profile dijawab di sini:

Perbedaan antara .bashrc dan .bash_profile

if [ -r ~/.profile ]; then . ~/.profile; fi
case "$-" in *i*) if [ -r ~/.bashrc ]; then . ~/.bashrc; fi;; esac

Untuk mengaktifkan pengujian (dan pembuatan profil), Anda dapat menggunakan ini

~ / .bash_profile:

#!/bin/bash

# ------------------------------------------------
export _DOT_BASH_PROFILE_0=`date  --rfc-3339=ns`
# ------------------------------------------------

if [ -f ~/.profile ] ; then
    . ~/.profile
fi

case "$-" in *i*) if [ -r ~/.bashrc ]; then . ~/.bashrc; fi;; esac

# ------------------------------------------------
export _DOT_BASH_PROFILE_1=`date  --rfc-3339=ns`
# ------------------------------------------------

~ / .zprofile:

#!/bin/zsh

# ------------------------------------------------
export _DOT_ZSH_PROFILE_0=`date  --rfc-3339=ns`
# ------------------------------------------------

if [ -f ~/.profile ] ; then
    . ~/.profile
fi

# no need to source, zsh already handle ~/.zshrc

###case "$-" in *i*) if [ -r ~/.zshrc ]; then . ~/.zshrc; fi;; esac

# ------------------------------------------------
export _DOT_ZSH_PROFILE_1=`date  --rfc-3339=ns`
# ------------------------------------------------

kemudian, untuk menguji:

chsh -s /bin/bash

ssh localhost
env

exit

ssh localhost env

ssh -t localhost bash -i -c env


chsh -s /bin/zsh

ssh localhost
env

exit

ssh localhost env

ssh -t localhost bash -i -c env

Jadi RVM / virtualenv harus masuk ~ / .profile, IMHO

Tapi ini TIDAK BEKERJA , kadang-kadang ...

Misalnya, virualenvwrapper hanya berfungsi jika shell yang menjalankan Xsession adalah bash "asli" (mengekspor BASH_VERSION)

Jika Anda menggunakan sistem dasbor , variabel lingkungan dan pengaturan jalur berfungsi, tetapi definisi fungsi virualenvwrapper tidak berfungsi karena skrip tidak kompatibel dengan POSIX.

Script tidak memberikan kesalahan tetapi berakhir tanpa definisi "workon" .

Jadi Anda dapat mengatur lingkungan di ~ / .profile , hanya untuk mengaktifkan eksekusi python yang benar dari klien dimulai langsung dari X:

export VIRTUAL_ENV="/home/mike/var/virtualenvs/myvirtualenv"
export PATH="$VIRTUAL_ENV/bin:$PATH"
unset PYTHON_HOME

https://gist.github.com/datagrok/2199506

https://www.bountysource.com/issues/9061991-setting-up-up-your-computer-virtualenvwrapper-linux-all

Tetapi untuk virualenwrapper Anda memiliki dua alternatif:

  1. sumbernya di ~ / .bash_profile atau ~ / .zprofile (atau ~ / .zlogin) ketika terminal bertindak sebagai shell login
  2. sertakan skrip dalam ~ / .bashrc atau ~ / zshrc

Ini berarti bahwa klien X (emacs misalnya) harus dimulai dari terminal shell dan bukan dari yang grafis!

"Aku tidak bisa mendapatkan kepuasan ..."

hute37
sumber
Kisah berbeda yang lengkap adalah menjalankan layanan dengan systemd. Beberapa alternatif yang mungkin adalah: menulis skrip wrapper , mendefinisikan lingkungan dalam file definisi "layanan" , membuang lingkungan dalam file "env" untuk bersumber di shell induk. Segalanya menjadi lebih sulit dengan RVM / virtualenv ...
hute37