~/.bash_profile ile ~/.bashrc arasındaki fark, Bash'in hangi tür kabukta hangi dosyayı okuduğundan gelir. Oturum açma kabuğu (login shell) başlarken önce /etc/profile, ardından ~/.bash_profile, ~/.bash_login ve ~/.profile dosyalarından ilk bulunanı okur. Oturum açma kabuğu olmayan etkileşimli bir kabuk ise yalnızca ~/.bashrc dosyasını okur. Betik çalıştıran etkileşimsiz kabuk bunların hiçbirine bakmaz; yalnızca BASH_ENV değişkeninde adı verilen dosyayı yükler. Bu yüzden yaygın düzen şudur: ~/.bash_profile içinde ~/.bashrc dosyası kaynak olarak eklenir, ortak ayarlar da ~/.bashrc içinde tutulur.
Bu yazıda iki temel ayrımı (etkileşimli mi, oturum açma kabuğu mu), her durumda okunan dosyaların sırasını, --norc, --rcfile, --noprofile gibi seçenekleri, kabuğun etkileşimli olup olmadığını bir başlangıç dosyası içinden nasıl anlayacağınızı ve hangi ayarın hangi dosyaya ait olduğunu örneklerle göreceksiniz. Bilgiler GNU Bash Reference Manual'ın 6.1 Invoking Bash, 6.2 Bash Startup Files ve 6.3 Interactive Shells bölümlerine dayanır.
İki ayrı soru: etkileşimli mi, oturum açma kabuğu mu?

Başlangıç dosyalarını anlamanın anahtarı, Bash'in kendine iki bağımsız soru sormasıdır. Birincisi: bu kabuk etkileşimli mi? Kılavuza göre etkileşimli kabuk, seçenek dışı argüman verilmeden (-s kullanılmadıkça) ve -c olmadan başlatılan, standart girdisi ile standart hata çıktısı terminale bağlı olan ya da -i seçeneğiyle zorla etkileşimli yapılan kabuktur. Kısacası komut isteminin (prompt) göründüğü ve sizin yazdığınız satırları okuyan kabuk etkileşimlidir; bash betik.sh ya da bash -c 'komut' ile başlayan kabuk değildir.
İkinci soru: bu bir oturum açma kabuğu mu? Kılavuz bunu çok net tanımlar: sıfırıncı argümanının ilk karakteri - olan ya da --login (kısaca -l) seçeneğiyle başlatılan kabuk oturum açma kabuğudur. Bir sisteme konsoldan ya da uzaktan bağlanıp oturum açtığınızda başlatılan kabuk genellikle bu türdendir; açık bir oturumun içinde bash yazarak açtığınız yeni kabuk ise oturum açma kabuğu değildir. Uzak bağlantının kendisi için SSH ile sunucuya bağlanma yazısına bakabilirsiniz.
Bu iki soru birbirinden bağımsızdır, dolayısıyla dört birleşim vardır. Aşağıdaki tablo her birleşimde hangi dosyaların okunduğunu özetler:
| Kabuk türü | Örnek başlatma | Okunan dosyalar |
|---|---|---|
| Etkileşimli, oturum açma | oturum açarken gelen kabuk, bash -l | /etc/profile, sonra ~/.bash_profile, ~/.bash_login, ~/.profile içinden ilk bulunan; çıkışta ~/.bash_logout |
| Etkileşimli, oturum açma değil | açık oturumda bash yazmak | ~/.bashrc |
| Etkileşimsiz | bash betik.sh, bash -c | yalnızca BASH_ENV ile verilen dosya |
| Etkileşimsiz, --login ile | bash -l betik.sh | oturum açma kabuğunun dosyaları (ilk satırdaki gibi) |
Oturum açma kabuğunun okuduğu dosyalar
Etkileşimli bir oturum açma kabuğu, ya da --login ile başlatılmış etkileşimsiz bir kabuk, önce sistem genelindeki /etc/profile dosyasını çalıştırır. Ardından ev dizininizde sırasıyla ~/.bash_profile, ~/.bash_login ve ~/.profile dosyalarını arar ve yalnızca var olan ve okunabilen ilkini çalıştırır. Bu ayrıntı sık gözden kaçar: ev dizininizde hem ~/.bash_profile hem ~/.profile varsa, Bash ikincisine hiç bakmaz. Daha önce ~/.profile içine yazdığınız bir PATH ayarı, birisi sonradan boş bir ~/.bash_profile oluşturduğu anda etkisiz kalır.
--noprofile seçeneği bu davranışı tamamen kapatır: ne /etc/profile ne de kişisel dosyalardan biri okunur. Etkileşimli bir oturum açma kabuğundan çıkarken, ya da etkileşimsiz bir oturum açma kabuğu exit komutunu çalıştırdığında, Bash varsa ~/.bash_logout dosyasını çalıştırır. Bu dosya oturum kapanırken ekranı temizlemek ya da geçici bir dosyayı silmek gibi küçük işler için uygundur. Dosyalardan biri var olup okunamıyorsa Bash bir hata bildirir; dosya adlarında tilde genişletmesi uygulanır.
Etkileşimli ama oturum açma kabuğu olmayan kabuk: ~/.bashrc
Oturum açma kabuğu olmayan etkileşimli bir kabuk yalnızca ~/.bashrc dosyasını okur. --norc seçeneği bunu engeller, --rcfile dosya (eş anlamlısı --init-file) ise ~/.bashrc yerine verdiğiniz dosyayı okutur. Kılavuz, bu iki kabuk türünü birleştirmek için tipik bir ~/.bash_profile satırı da önerir: oturuma özgü işlemlerden önce ya da sonra ~/.bashrc dosyasını kaynak olarak eklemek. Böylece alias, fonksiyon ve istem ayarlarınızı tek bir yerde tutarsınız ve her iki kabuk türü de onları görür.
# ~/.bash_profile
# Ortam değişkenleri burada: oturum başında bir kez ayarlanır
export EDITOR=nano
# Etkileşimli ayarların tamamı ~/.bashrc içinde; onu buradan yükleyin
if [ -f ~/.bashrc ]; then . ~/.bashrc; fi. komutu source ile aynıdır ve dosyayı ayrı bir süreçte değil, o anki kabukta çalıştırır; bu yüzden dosyada tanımlanan alias ve fonksiyonlar kabukta kalır. Ayrıntılar için source ve nokta komutu yazısına bakın.
~/.bashrc dosyasının başına, kabuk etkileşimli değilse dosyanın geri kalanını atlayan bir koruma koymak da yaygın bir alışkanlıktır. Bunun nedeni bir sonraki bölümde göreceğiniz bir istisnadır: Bash bazı durumlarda etkileşimsiz çalışırken de bu dosyayı okuyabilir.
# ~/.bashrc
# Etkileşimli değilsek burada dur ($- içinde i harfi yoksa)
case $- in
*i*) ;;
*) return ;;
esac
alias ll='ls -lA'
PS1='\u@\h:\w\$ 'Kaynak olarak okunan bir dosyada return, dosyanın geri kalanını çalıştırmadan okuma işlemini bitirir. İstemi (PS1) özelleştirmenin tüm ayrıntıları PS1 prompt özelleştirme, alias tanımlarının kuralları ise Bash alias tanımlama yazısında.
Etkileşimsiz kabuklar ve BASH_ENV

Bir betiği çalıştıran etkileşimsiz kabuk ~/.bashrc dosyasını okumaz. Bunun yerine ortamda BASH_ENV değişkenine bakar; değişken varsa değerini genişletir ve ortaya çıkan adı bir dosya olarak okuyup çalıştırır. Kılavuzun belirttiği önemli bir ayrıntı: bu dosya adı PATH üzerinde aranmaz, bu yüzden göreli ya da tam yol vermeniz gerekir. Aşağıdaki betik, nasıl bir kabukta çalıştığını kendisi raporluyor; aynı betiği bir kez düz, bir kez BASH_ENV ile çalıştırıyoruz:
# ortam.sh içeriği: ORTAM_DEGERI="ortam.sh okundu"
# kontrol.sh:
case $- in
*i*) echo "etkileşimli" ;;
*) echo "etkileşimsiz" ;;
esac
if [[ -v PS1 ]]; then echo "PS1 tanımlı"; else echo "PS1 tanımsız"; fi
shopt -q login_shell && echo "oturum açma kabuğu" || echo "oturum açma kabuğu değil"
echo "BASH_ENV ile gelen: ${ORTAM_DEGERI:-yok}"
# $ bash kontrol.sh
# çıktı:
# etkileşimsiz
# PS1 tanımsız
# oturum açma kabuğu değil
# BASH_ENV ile gelen: yok
# $ BASH_ENV=./ortam.sh bash kontrol.sh
# çıktı: (ilk üç satır aynı, son satır değişir)
# BASH_ENV ile gelen: ortam.sh okundulogin_shell seçeneği shopt ile yalnızca okunabilir; kabuk oturum açma kabuğu olarak başladıysa Bash onu kendisi açar ve değeri değiştirilemez. Betiklerinizi zamanlanmış görev olarak çalıştırdığınızda da kabuk etkileşimsizdir; ~/.bashrc içine koyduğunuz bir PATH eklemesine güvenmemek bu yüzden önemlidir. Zamanlama tarafı için cron job rehberi yazısına bakabilirsiniz.
Kabuk etkileşimli mi? Başlangıç dosyası içinden anlamak
Kılavuz iki yöntem önerir. Birincisi $- özel parametresidir: o anda açık olan tek harfli seçenekleri içerir ve kabuk etkileşimliyse içinde i harfi bulunur. Yukarıdaki case $- in *i*) kalıbı tam olarak bunu sınar. İkincisi PS1 değişkenidir: etkileşimli kabuklarda ayarlıdır, etkileşimsiz kabuklarda ayarlı değildir. Bu ikinci yöntem, PS1 değişkenini ortama aktaran (export) bir sistemde yanıltıcı olabilir, çünkü dışa aktarılan değişken etkileşimsiz alt kabuklara da miras kalır. Bu nedenle $- kontrolü daha sağlamdır.
Aşağıdaki deneme, sahte bir ev dizini hazırlayıp Bash'i -i ile zorla etkileşimli başlatıyor ve komutları bir boru üzerinden veriyor. Terminal bağlı olmadığı için Bash iş denetimiyle ilgili iki uyarı basar; onları grep -v ile ayıklıyoruz. Gerçek ev dizininize dokunmamak için HOME yalnızca bu komut için değiştiriliyor:
mkdir -p ./ev
printf '%s\n' 'echo ".bashrc okundu"' "PS1='\$ '" > ./ev/.bashrc
echo 'echo ".bash_profile okundu"' > ./ev/.bash_profile
echo 'echo "seçenekler: $-"' | HOME="$PWD/ev" bash -i 2>&1 | grep -v -e 'process group' -e 'job control'
# çıktı:
# .bashrc okundu
# $ echo "seçenekler: $-"
# seçenekler: hiBHs
# $ exit
echo 'echo "betik gibi"' | HOME="$PWD/ev" bash
# çıktı: betik gibiİlk çağrıda kabuk etkileşimli ama oturum açma kabuğu değil; bu yüzden ~/.bash_profile okunmadı, yalnızca ~/.bashrc okundu. $- içindeki i harfi etkileşimliliği, s harfi komutların standart girdiden okunduğunu gösterir. İkinci çağrıda -i olmadığı ve girdi terminal olmadığı için kabuk etkileşimsizdir ve hiçbir başlangıç dosyasını okumaz. Oturum açma kabuğunu bu şekilde denemedik, çünkü o durumda sistemin /etc/profile dosyası da çalışır ve çıktısı sistemden sisteme değişir.
Özel durumlar: sh adı, POSIX modu, uzak kabuk ve setuid
Bash sh adıyla çağrılırsa tarihsel sh davranışını taklit etmeye çalışır. Oturum açma kabuğu olarak yalnızca /etc/profile ve ~/.profile okunur; etkileşimli kabukta ENV değişkeninde adı verilen dosya çalıştırılır ve başka hiçbir başlangıç dosyası okunmadığı için --rcfile etkisizdir. sh olarak çağrılan etkileşimsiz kabuk hiçbir başlangıç dosyası okumaz ve Bash dosyaları okuduktan sonra POSIX moduna geçer. --posix ile başlatılan kabuk da POSIX standardına uyar: etkileşimliyse yalnızca ENV dosyasını okur. Bu modun diğer farkları Bash ve sh farkı, POSIX modu yazısında.
Daha az bilinen bir istisna uzak kabuk servisleridir. Kılavuza göre Bash, standart girdisinin bir ağ bağlantısına bağlı olduğunu anlayabildiği durumlarda (örneğin sshd tarafından bir komut çalıştırmak için başlatıldığında) etkileşimsiz olsa bile ~/.bashrc dosyasını okur. sh olarak çağrıldıysa bunu yapmaz. Bu, uzaktan tek bir komut çalıştırdığınızda ~/.bashrc içindeki echo satırlarının komut çıktısına karışabileceği anlamına gelir; yukarıdaki etkileşim koruması bu yüzden faydalıdır. Son olarak, Bash etkin kullanıcı (ya da grup) kimliği gerçek kimlikten farklıyken başlatılırsa ve -p verilmemişse hiçbir başlangıç dosyası okunmaz ve etkin kimlik gerçek kimliğe eşitlenir.
Hangi ayar hangi dosyaya?

Genel ilke şudur: bir kez ayarlanıp alt süreçlere miras kalması gerekenler oturum açma dosyasına, her etkileşimli kabukta yeniden tanımlanması gerekenler ~/.bashrc dosyasına gider. export edilen değişkenler ortamın parçasıdır ve alt süreçlere aktarılır; bu yüzden PATH, EDITOR gibi değişkenleri oturum başında bir kez ayarlamak yeterlidir. Alias tanımları ve kabuk seçenekleri ise ortamla aktarılmaz; her etkileşimli kabuk onları kendi başlangıç dosyasından yeniden okumalıdır. Değişkenlerin ve export komutunun ayrıntıları Bash değişkenler ve atama yazısında.
| Ayar | Önerilen dosya | Neden |
|---|---|---|
| export PATH=..., export EDITOR=... | ~/.bash_profile (ya da ~/.profile) | ortamla alt süreçlere aktarılır, bir kez yeter |
| alias, fonksiyon | ~/.bashrc | ortamla aktarılmaz, her kabukta yeniden tanımlanmalı |
| PS1, PROMPT_COMMAND | ~/.bashrc | yalnızca etkileşimli kabukta anlamlı |
| HISTSIZE, HISTCONTROL, shopt -s histappend | ~/.bashrc | komut geçmişi etkileşimli kabuğun özelliği |
| oturum kapanırken temizlik | ~/.bash_logout | oturum açma kabuğu çıkarken çalışır |
Geçmiş ayarlarının ne işe yaradığı Bash history komut geçmişi yazısında, shopt seçenekleri ise Bash shopt seçenekleri yazısında anlatılıyor.
Etkileşimli kabukta neler farklıdır?
Başlangıç dosyalarını okumak, etkileşimli kabuğun davranış farklarından yalnızca biridir. Kılavuzun 6.3.3 bölümü bu farkları uzun bir liste halinde sayar; en çok işinize yarayacak olanlar şunlardır:
- İş denetimi (job control) varsayılan olarak açıktır; arka plan işlerini jobs, fg ve bg ile yönetebilirsiniz.
- Birincil istem gösterilmeden önce
PROMPT_COMMANDiçindeki komutlar çalışır; çok satırlı komutların devam satırlarındaPS2gösterilir. - Komutlar Readline kütüphanesiyle okunur, bu yüzden klavye kısayolları çalışır.
- Komut geçmişi ve
!ile geçmiş genişletmesi varsayılan olarak açıktır; kabuk çıkarken geçmiş$HISTFILEdosyasına yazılır. - Alias genişletmesi varsayılan olarak yapılır; betiklerde ise kapalıdır.
set -uaçıkken tanımsız değişkene başvurmak ya da sözdizimi hatası yapmak kabuğu kapatmaz; yalnızca o komut başarısız olur.- Tuzak (trap) kurulmamışsa
SIGTERMyok sayılır,SIGINTyakalanıp işlenir.
Sık yapılan hatalar
- Ayarı yanlış dosyaya koymak:
~/.bashrciçine yazılan alias, oturum açma kabuğunda görünmez; çünkü o kabuk~/.bashrcdosyasını kendiliğinden okumaz. Çözüm,~/.bash_profileiçinden~/.bashrcdosyasını kaynak olarak eklemektir. - Üç dosyanın hepsinin okunduğunu sanmak:
~/.bash_profile,~/.bash_loginve~/.profilearasından yalnızca ilk bulunan çalışır. - Döngüsel kaynak ekleme:
~/.bashrciçinden~/.bash_profiledosyasını, o dosyadan da yeniden~/.bashrcdosyasını eklemek, dosyaların birbirini sonsuza kadar çağırmasına yol açar. Ekleme her zaman tek yönlü olmalı. - Her alt kabukta büyüyen PATH:
PATH=$PATH:~/binsatırını~/.bashrciçine koyarsanız, açtığınız her iç içe kabuk aynı dizini bir kez daha ekler. Bu tür ortam ayarları oturum açma dosyasında daha temiz durur. - ~/.bashrc içinde çıktı üretmek: uzaktan çalışan komutlar da bu dosyayı okuyabildiği için, koşulsuz bir
echosatırı komutların çıktısını kirletebilir. Mesajları etkileşim korumasının altına koyun. - Değişikliği uyguladığını sanmak: dosyayı düzenlemek açık kabuğu değiştirmez.
source ~/.bashrcçalıştırın ya da yeni bir kabuk açın.
Sık Sorulan Sorular
.profile ile .bash_profile arasındaki fark nedir?
İkisi de oturum açma kabuğunun okuduğu dosyalardır, ama ~/.bash_profile Bash'e özgüdür ve önce aranır. ~/.profile ise Bash sh adıyla çağrıldığında da okunan, daha genel bir dosyadır. ~/.bash_profile varsa Bash oturum açarken ~/.profile dosyasını okumaz; ikisini birlikte kullanmak istiyorsanız birini diğerinin içinden kaynak olarak ekleyin.
.bashrc değişikliklerini kabuğu kapatmadan nasıl uygularım?
source ~/.bashrc ya da kısaca . ~/.bashrc komutu dosyayı o anki kabukta yeniden çalıştırır. Silinen bir alias bu yolla kaybolmaz, çünkü dosya yalnızca yeni tanımları ekler; eskisini kaldırmak için unalias kullanın ya da yeni bir kabuk açın.
Betiğim neden .bashrc içindeki alias ve fonksiyonları görmüyor?
Betik etkileşimsiz bir kabukta çalışır ve bu kabuk ~/.bashrc dosyasını okumaz. Betiğin ihtiyaç duyduğu tanımları betiğin içine yazın ya da ortak bir dosyaya koyup betiğin başında source ile ekleyin. Betiklerde alias yerine fonksiyon kullanmak da daha güvenlidir.
Hangi kabukta olduğumu nasıl anlarım?
Etkileşimlilik için $- içinde i harfine, oturum açma kabuğu olup olmadığı için shopt -q login_shell komutunun çıkış durumuna bakın. Kabuğun iç içe kaçıncı Bash olduğunu SHLVL değişkeni gösterir; her yeni Bash örneği bu değeri bir artırır.
Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.
İlgili içerikler: Bash öğrenme rehberi · source ve nokta komutu · Bash alias tanımlama · PS1 özelleştirme · komut geçmişi · Bash ve sh farkı · Bash script yazma · Linux nedir