Bash komut istemi (prompt) PS1 değişkeninin değeridir; kabuk her yeni komut beklerken bu değeri çözer ve ekrana basar. İstemi değiştirmek için PS1 değişkenine \u (kullanıcı adı), \h (makine adı), \w (çalışma dizini) ve \$ (root için #, diğer kullanıcılar için $) gibi ters eğik çizgili kaçışlar içeren bir değer atarsınız, örneğin PS1='\u@\h:\w\$ '. Kalıcı olması için bu satırı ~/.bashrc dosyanıza eklersiniz. Renk gibi ekranda yer kaplamayan terminal dizilerini ise \[ ve \] arasına almanız gerekir.

Bu yazıda istem değişkenlerinin tamamını (PS0, PS1, PS2, PS3, PS4), kaçış karakterlerinin listesini, PROMPT_DIRTRIM ve PROMPT_COMMAND değişkenlerini, tek ve çift tırnak seçiminin istemi nasıl etkilediğini ve istemi etkileşimli kabuk açmadan ${değişken@P} ile nasıl deneyebileceğinizi göreceksiniz. Kaynak, GNU Bash Reference Manual'ın 6.9 Controlling the Prompt bölümü ile değişken açıklamalarıdır.

İstem değişkenleri: PS0, PS1, PS2, PS3, PS4

İstem değişkenleri: PS0, PS1, PS2, PS3, PS4: her yeni komuttan önce (birincil istem), çok satırlı komutun devam satırlarında, komut okunduktan sonra, çalışmadan önce, select...

Bash'te tek bir istem yoktur; farklı anlarda farklı değişkenler gösterilir. Etkileşimli kabuk bir komutun ilk satırını okumadan önce PS1, çok satırlı bir komutun ikinci ve sonraki satırları için PS2 gösterir. PS0 ise komut okunduktan sonra ama çalıştırılmadan önce basılır. PS3, select menüsünün seçim istemidir; PS4 de set -x izleme satırlarının önüne eklenir. Varsayılan değerler kılavuzda şöyle verilir:

DeğişkenNe zaman gösterilirVarsayılan
PS1her yeni komuttan önce (birincil istem)\s-\v\$
PS2çok satırlı komutun devam satırlarında>
PS0komut okunduktan sonra, çalışmadan önceyok
PS3select komutunun seçim istemindeayarlı değilse #?
PS4set -x ile izlenen her komutun önünde+

Varsayılan PS1 değeri \s-\v\$ kabuğun adını, sürümünü ve $ işaretini gösterir; bash-5.2$ gibi bir istem görüyorsanız kimse PS1 ayarlamamış demektir. PS4 için ayrıca bir kural vardır: genişletilmiş değerin ilk karakteri iç içe düzey sayısı kadar tekrarlanır; derin bir alt kabuktaki izleme satırının +++ ile başlaması bundandır. PS4 ile hata ayıklamayı set -x ile hata ayıklama yazısında ayrıntılı ele alıyoruz.

Kaçış karakterleri tablosu

Kılavuzdaki kaçışların tamamı aşağıdaki tabloda. Bunlar yalnızca istem değişkenlerinde (PS0, PS1, PS2, PS4) ve aşağıda göreceğiniz @P dönüşümünde anlam taşır; sıradan bir echo içinde çözülmezler.

KaçışAnlamı
\uo anki kullanıcının adı
\h ve \Hmakine adının ilk noktaya kadar olan kısmı ve tamamı
\wçalışma dizini ($PWD), ev dizini ~ ile kısaltılmış
\Wçalışma dizininin yalnızca son bileşeni, ev dizini ~ olarak
\$etkin kullanıcı kimliği 0 ise #, değilse $
\t, \T, \@, \A24 saat SS:DD:ss, 12 saat SS:DD:ss, 12 saat öö/ös, 24 saat SS:DD
\dtarih, "Tue May 26" biçiminde
\D{biçim}strftime biçimiyle tarih ve saat; süslü parantez zorunlu
\jkabuğun yönettiği iş sayısı
\!bu komutun geçmiş numarası
\#bu komutun oturumdaki komut numarası
\skabuğun adı ($0 değerinin son bileşeni)
\v ve \VBash sürümü ve yama düzeyiyle birlikte sürüm
\lterminal aygıtı adının son bileşeni
\n, \r, \a, \eyeni satır, satır başı, zil, escape karakteri
\nnnsekizlik değeri nnn olan karakter
\\ters eğik çizginin kendisi
\[ ve \]ekranda yer kaplamayan karakter dizisinin başı ve sonu

\! ile \# farkı sık karıştırılır. Geçmiş numarası komutun geçmiş listesindeki sırasıdır ve geçmiş dosyasından yüklenen eski komutları da sayar; komut numarası ise yalnızca bu oturumda çalıştırılan komutların sırasıdır. Bu yüzden yeni açtığınız bir kabukta \# küçük, \! büyük bir sayı gösterebilir. Geçmiş numarasıyla !123 gibi bir komutu yeniden çalıştırabilirsiniz; bunun ayrıntıları Bash history komut geçmişi yazısında. \j ise arka planda kaç işiniz olduğunu gösterir; iş yönetimi arka plan işleri yazısında.

Saat ve tarih için hazır kaçışlar yetmiyorsa \D{biçim} kullanın: süslü parantez içindeki biçim C kütüphanesinin strftime fonksiyonuna verilir, örneğin \D{%H:%M} saat ile dakikayı, \D{%d.%m.%Y} gün, ay ve yılı yazar. Süslü parantezler zorunludur; içi boş bırakılırsa yerel ayara göre bir saat gösterimi kullanılır. Sunucu loglarıyla karşılaştırma yaparken istemde saatin görünmesi, bir komutun ne zaman çalıştırıldığını terminal geçmişinden okumayı kolaylaştırır.

İstemi etkileşimli kabuk açmadan denemek: ${değişken@P}

İstemi etkileşimli kabuk açmadan denemek: ${değişken@P}

Yeni bir PS1 değerini denemek için her seferinde istemi değiştirmek zorunda değilsiniz. Parametre genişletmesinin @P dönüşümü, bir değişkenin değerini istem dizesi gibi çözer ve sonucu verir. Bu, istem kaçışlarını bir betik içinde bile sınamanızı sağlar. Aşağıdaki örnek, kararlı bir çıktı elde etmek için HOME değişkenini geçici olarak deneme dizinine eşitliyor; böylece \w ev dizinini ~ ile kısaltıyor:

bash
HOME=$PWD
mkdir -p ./site/public/css
cd ./site/public/css

k='\w';        echo "${k@P}"    # çıktı: ~/site/public/css
k='\W';        echo "${k@P}"    # çıktı: css
k='[\w]\$ ';   echo "${k@P}"    # çıktı: [~/site/public/css]$
k='bir\niki';  echo "${k@P}"
# çıktı:
#   bir
#   iki

PROMPT_DIRTRIM=2
k='\w';        echo "${k@P}"    # çıktı: ~/.../public/css
cd "$HOME"
k='\w|\W';     echo "${k@P}"    # çıktı: ~|~

\$ burada $ verdi, çünkü örnek root olmayan bir kullanıcıyla çalıştı; aynı satır root olarak # verir. PROMPT_DIRTRIM sıfırdan büyük bir sayıya ayarlandığında \w ve \W yalnızca o kadar son dizin bileşenini tutar, atılan kısmın yerine üç nokta koyar. Derin dizin ağaçlarında çalışıyorsanız istemin satırı doldurmasını bu değişkenle önleyebilirsiniz. @P ve diğer dönüşümler string işlemleri yazısında da geçiyor.

Renkli istem ve \[ \] kuralı

İstemi renklendirmek için terminalinize renk değiştiren escape dizileri gönderirsiniz. Bu diziler ekranda görünür bir karakter oluşturmaz, ama kabuk bunu kendiliğinden bilemez. Kılavuz \[ ile \] kaçışlarını tam bu iş için tanımlar: aralarında kalan karakterler yazdırılmayan bir dizi olarak işaretlenir. İşaretlemeyi unutursanız bu baytlar da ekranda yer kaplayan karakterler gibi sayılır; bunun sonucunda uzun komutlarda satır kaydırma ve imleç konumu bozuk görünebilir. Kural basittir: her renk kodunu kendi \[ ... \] çiftine alın.

bash
# ~/.bashrc içinde: yeşil kullanıcı@makine, mavi dizin, sonra sıfırlama
PS1='\[\e[32m\]\u@\h\[\e[0m\]:\[\e[34m\]\w\[\e[0m\]\$ '

Örnekteki \e[32m, \e[34m ve \e[0m kodları yaygın ANSI terminal dizileridir; hangi rengi verdikleri terminalinize ve temanıza bağlıdır, bu yüzden kendi terminal belgenize bakın. \e istem içinde escape karakterine çözülür. Bir istemin ekranda kapladığı alanı @P ile denetleyebilirsiniz; aşağıdaki çıktıda \[ ve \] işaretlerinin kendisi görünmez, yalnızca escape dizileri kalır:

bash
renkli='\[\e[32m\]\W\[\e[0m\]\$ '
HOME=$PWD
printf '%q\n' "${renkli@P}"
# çıktı: $'\E[32m~\E[0m$ '

Tek tırnak mı çift tırnak mı? promptvars

İstem çözüldükten sonra Bash sonucu bir de parametre genişletmesi, komut ikamesi, aritmetik genişletme ve tırnak kaldırma işleminden geçirir. Bu davranışı promptvars kabuk seçeneği yönetir ve varsayılan olarak açıktır. Pratik sonucu şudur: PS1 değerini tek tırnakla yazarsanız içindeki $degisken ya da $(komut) her istem gösterilişinde yeniden hesaplanır; çift tırnakla yazarsanız atama anında bir kez hesaplanır ve istem o değerde donar:

bash
sayac=1
tek='[$sayac] \$ '
cift="[$sayac] \\$ "
sayac=2
echo "tek tırnak:  ${tek@P}"     # çıktı: tek tırnak:  [2] $
echo "çift tırnak: ${cift@P}"    # çıktı: çift tırnak: [1] $
shopt -u promptvars
echo "kapalı:      ${tek@P}"     # çıktı: kapalı:      [$sayac] $ 

Çift tırnaklı sürümde ters eğik çizgiyi iki kez yazdık, çünkü çift tırnak içinde \$ zaten $ olurdu ve istem kaçışı kaybolurdu. Tırnak kurallarının ayrıntısı tek tırnak ve çift tırnak farkı yazısında. Kılavuz bu ikinci genişletme turuna dair bir uyarı da yapar: istem kaçışlarıyla üretilen parçalar bir komut ikamesinin içinde yer alırsa ya da kelime genişletmesi için özel karakterler içerirse istenmeyen yan etkiler doğabilir. Bu yüzden istem kaçışlarını komut ikamesinin içine yerleştirmekten kaçının ve istemde güvenmediğiniz kaynaklardan gelen metni değerlendirmeyin.

İstem içinde komut ikamesi kullanmak mümkündür, ama her istemde çalışacağını unutmayın: yavaş bir komut her Enter tuşundan sonra beklemenize yol açar. Komut ikamesinin kuralları Bash komut ikamesi yazısında.

PS3 ve PS4 ile küçük örnekler

İki yardımcı istem betiklerde de işe yarar. select komutu bir menü basar ve seçimi PS3 istemiyle sorar; PS3 ayarlı değilse istem #? olur. Menü ve istem standart hataya yazıldığı için aşağıdaki örnekte onları 2>&1 ile standart çıktıya katıyor, seçimi de bir here string ile veriyoruz:

bash
PS3='Ortam seçin: '
select ortam in test canli; do
  echo "seçilen: $ortam"
  break
done 2>&1 <<< 2
# çıktı:
#   1) test
#   2) canli
#   Ortam seçin: seçilen: canli

PS4 de PS1 gibi genişletildiği için içine değişken koyabilirsiniz. Aşağıdaki satır, set -x izleme çıktısının her satırına komutun betikteki satır numarasını ekliyor; uzun betiklerde hatanın yerini bulmayı çok kolaylaştırır. Tek tırnak burada da şart, aksi halde LINENO atama anında bir kez hesaplanırdı:

bash
PS4='+ ${LINENO}: '
set -x
x=5
echo "$x"
# çıktı (standart hataya):
#   + 3: x=5
#   + 4: echo 5
# çıktı: 5

Here string sözdizimi here document ve here string, yönlendirme sırası stdout ve stderr yönlendirme yazısında anlatılıyor.

PROMPT_COMMAND: istemden önce komut çalıştırmak

PROMPT_COMMAND ayarlıysa Bash birincil istemi basmadan hemen önce içindeki komutu çalıştırır. Değişken bir diziyse dizinin ayarlı her elemanı sırayla bir komut olarak çalışır; dizi değilse değerin kendisi tek bir komut olarak kullanılır. Dizi biçimi, farklı araçların kendi komutlarını birbirinin üzerine yazmadan eklemesine izin verir: PROMPT_COMMAND+=('komut'). Tipik kullanımlar son komutun çıkış durumunu göstermek, terminal başlığını güncellemek ya da komut geçmişini her istemde dosyaya eklemektir.

Etkileşimli bir kabuğu denetim altında görmek için kabuğu -i ile başlatıp kendi başlangıç dosyamızı --rcfile ile verelim ve komutları bir dosyadan okutalım. Terminal bağlı olmadığı için basılan iki iş denetimi uyarısını yine ayıklıyoruz:

bash
cat > ./deneme_rc <<'SON'
PS1='[\#] $ '
PS2='devam> '
PROMPT_COMMAND='echo "(önceki durum: $?)"'
SON
printf '%s\n' 'echo bir' 'false' 'for i in 1 2' 'do echo $i' 'done' > ./girdi.txt

bash --rcfile ./deneme_rc -i < ./girdi.txt 2>&1 | grep -v -e 'process group' -e 'job control'
# çıktı:
#   (önceki durum: 0)
#   [1] $ echo bir
#   bir
#   (önceki durum: 0)
#   [2] $ false
#   (önceki durum: 1)
#   [3] $ for i in 1 2
#   devam> do echo $i
#   devam> done
#   1
#   2
#   (önceki durum: 0)
#   [4] $ exit

Çıktıda üç şeyi birlikte görüyorsunuz: PROMPT_COMMAND her istemden önce çalıştı ve $? ile bir önceki komutun durumunu yazdı; \# her komutta bir arttı; for döngüsünün devam satırlarında PS2 gösterildi. Dikkat edilecek nokta: PROMPT_COMMAND içindeki ilk komut $? değerini okumadan önce başka bir komut çalıştırırsanız, gördüğünüz durum artık kullanıcının komutuna değil, o ara komuta ait olur. Durumu bir değişkene ilk iş olarak kaydedin. Çıkış durumlarının anlamı exit kodları yazısında.

bash
# ~/.bashrc: son komut başarısızsa istemin başında durumu kırmızı göster
istemi_kur() {
  local d=$?                       # ilk iş: durumu sakla
  if (( d != 0 )); then
    PS1='\[\e[31m\]['"$d"']\[\e[0m\] \w\$ '
  else
    PS1='\w\$ '
  fi
}
PROMPT_COMMAND=(istemi_kur)

Bu kalıpta fonksiyon her istemden önce PS1 değerini yeniden kuruyor. Durum kodu çift tırnakla araya eklendiği için atama anında sabitleniyor, istem kaçışları ise tek tırnak içinde kaldığı için istem gösterilirken çözülüyor. İstem parçalarını fonksiyonlarda hazırlayıp tek bir PS1 içinde birleştirmek, uzun ve okunmaz tek satırlık istemlerden çok daha kolay bakım sağlar.

Readline ile ilgili istem ayarları

Readline kütüphanesinin show-mode-in-prompt değişkeni açıksa, istemin son satırının başına o anki düzenleme kipini gösteren bir metin eklenir: emacs kipinde varsayılan olarak @, vi kipinde (ins) ya da (cmd). Bu metinler emacs-mode-string, vi-ins-mode-string ve vi-cmd-mode-string değişkenleriyle değiştirilebilir; içlerinde yazdırılmayan dizileri işaretlemek için \[ \] yerine \1 ve \2 kullanılır. Bu ayarların yeri ~/.inputrc dosyasıdır ve Readline kısayolları yazısında anlatılıyor.

Sık yapılan hatalar

Sık yapılan hatalar: Renk kodlarını \[ \] dışına koymak, Çift tırnakla dinamik değer beklemek, Ayarı yalnızca komut satırında yapmak, PROMPT_COMMAND değerini ezmek
  • Renk kodlarını \[ \] dışına koymak: istem doğru görünür ama uzun satırlarda imleç kayar. Her escape dizisini işaretleyin.
  • Çift tırnakla dinamik değer beklemek: PS1="$(git branch)" yalnızca atama anındaki değeri gösterir. Her istemde hesaplanması için tek tırnak kullanın.
  • Ayarı yalnızca komut satırında yapmak: yeni kabukta kaybolur. Kalıcı istem için satırı ~/.bashrc dosyasına ekleyin; hangi dosyanın ne zaman okunduğu .bashrc ve .bash_profile farkı yazısında.
  • PROMPT_COMMAND değerini ezmek: başka bir araç zaten bir komut eklediyse PROMPT_COMMAND='...' onu siler. Dizi biçiminde += ile ekleyin.
  • İstemde yavaş komut çalıştırmak: istemdeki her komut ikamesi her Enter sonrası yeniden çalışır.
  • \$ yerine düz $ yazmak: düz $ root olduğunuzu istemden anlamanızı engeller; \$ bunu otomatik gösterir.

Sık Sorulan Sorular

PS1 değişikliğini kalıcı nasıl yaparım?

PS1=... satırını ~/.bashrc dosyanıza ekleyin ve source ~/.bashrc ile yeniden yükleyin. Oturum açma kabuğunuz ~/.bashrc dosyasını okumuyorsa, ~/.bash_profile içinden onu kaynak olarak eklediğinizden emin olun.

İstemi iki satıra nasıl bölerim?

\n kaçışını kullanın: PS1='\w\n\$ ' dizini birinci satırda, $ işaretini ikinci satırda gösterir. Uzun dizin yollarında komut yazacağınız alanı genişletmenin pratik bir yoludur.

İstemde neden bash-5.2$ yazıyor?

Bu, PS1 değişkeninin varsayılan değeri olan \s-\v\$ sonucudur: kabuğun adı, sürümü ve $. Genellikle --norc ile başlatılmış ya da ~/.bashrc dosyası okunmamış bir kabuğu işaret eder.

Root olduğumda istemi farklı göstermek mümkün mü?

\$ kaçışı bunu en basit haliyle zaten yapar. Daha belirgin bir uyarı istiyorsanız ~/.bashrc içinde etkin kullanıcı kimliğini tutan salt okunur EUID değişkenine bakabilirsiniz: if (( EUID == 0 )); then PS1='\[\e[31m\]\u@\h\[\e[0m\]:\w\$ '; fi gibi bir satır, root kabuğunda istemi farklı renkte kurar. Sunucularda yanlış kullanıcıyla komut çalıştırma riskini azaltmanın ucuz bir yoludur. Aritmetik koşul sözdizimi için Bash aritmetik işlemler yazısına bakın.

PS0 ne işe yarar?

PS0 komut okunduktan sonra, çalışmaya başlamadan önce basılır. Örneğin uzun süren komutlardan önce bir ayırıcı çizgi ya da başlangıç saati (\t) yazdırmak için kullanılabilir; PS1 gibi çözülü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 · .bashrc ve .bash_profile farkı · komut geçmişi · Readline kısayolları · set -x ve PS4 · tırnak farkları · exit kodları · SSH ile bağlanma