Satır uzunluğu hesaplamasını bozmadan Bash PS1'e komutlar nasıl dahil edilir?


13

Tonin , varsayılan istemimdeki bir hataya dikkat çekti . Minimal örnek:

  1. PS1'i ayarlayın:

    PS1='$(exit_code=$?; [[ $exit_code -eq 0 ]] || printf %s $(tput setaf 1) $exit_code $(tput sgr0) " ")$ '

    Bu noktada, bilgi istemi şöyle görünür:

    $ 
  2. Şimdi çalıştırarak çıkış kodu çıkışını tetikleyin:

    false

    Şimdi istem satırın başında çıkış kodunu kırmızı renkte içerir:

    1 $ 
  3. Basın Ctrl- r.
  4. "False" yazın. Şimdi bilgi istemi yalnızca aramayı içerir:

    (reverse-i-search)`false': false
  5. Düğmesine basın Enter.

Ortaya çıkan terminal geçmişi şimdi aşağıdakileri içerir:

1 $ch)`false': false

Beklenen çıktı:

1 $ false

Yani, geçmiş arama çıktısı komut istemiyle karıştırılmış ve çalıştırılan gerçek komutu gizliyor gibi görünüyor .

Bunu kullanarakPROMPT_COMMAND bu soruna geçici bir çözüm denedim :

set_exit_code() {
    exit_code=$?
    [[ $exit_code -eq 0 ]] || printf %s $(tput setaf 1) $exit_code $(tput sgr0) " "
}
set_bash_prompt() {
    PS1='$(set_exit_code)$ ' # Double quotes give the same result
}
PROMPT_COMMAND=set_bash_prompt

Bu işe yaramıyor gibi görünüyor - çizgi arama ve çalıştırmadan önce eskisi gibi görünüyor.

Bunu nasıl düzeltebilirim?


Yanıtlar:


8

Cevabı askubuntu.com'da buldum . @qeirha, bash'a karakter dizisinin istemin uzunluğunda sayılmaması gerektiğini söylemiş ve bunu içine alarak yapmalısınız \[ \]. Sağlanan örneğe dayanarak, bir çözüm var:

red=$(tput setaf 1)

reset=$(tput sgr0)

[ "$PS1" = "\\s-\\v\\\$ " ] && PS1='$(exit_code=$?; [[ $exit_code -eq 0 ]] || printf %s \[$red\] $exit_code \[$reset\] " ")$ '

Bunun için Ubuntu'ya gitmeye gerek yok . Burada da bu soruya yeterince yanıtımız var.
manatwork

@Manatwork tavsiyeniz için teşekkür ederiz! Açıklama için uygun kredi vermek istedim ve referansı nezaket olarak sağladım.
Timothy Martin

Kredi vermek sorun değil. Ancak sorundan bahsederken: Markdown'dan kaybolmak için kaçan ters eğik çizgiler kullanıldı, bu yüzden düzünüz [[yayınınızda] oldu, bu nedenle görüntülenen kod, terminale kopyalanarak işlevsel değildi. Bu, satır içi kod veya kod bloğu işaretlemesi kullanılarak önlenebilir. (
Yazılarımı

1
D'oh! Zaten diğer PS1kod için aynı sorunu düzelttim , neden bunu görmedim?
l0b0

1
PS1='$(exit_code=$?; [[ $exit_code -eq 0 ]] || printf %s \[$(tput setaf 1)\] $exit_code \[$(tput sgr0)\] " ")$ '

(Maalesef burada hiçbir açıklama. Bkz düzgün PS1 özelleştirme? Ya istemi uzunluk hesaplama sorunları ve ilgili başka bir soru \[.. \].)


İkinci @ l0b0 soru, ben PS1 kullanarak eklemek ve \[...\]tek bir dize istemi oluşturmak istediğiniz tüm kodu koyabilirsiniz sürece iyi çalışır. Ancak, kodunuzu küçük işlevlere bölmek istiyorsanız, başlangıç ​​ve bitiş parantezlerini aynı dizeye / işleve koyamayacağınız bir noktaya gelirsiniz. Ve bu çizgi sarmayı kırıyor. Eğer her bilgi isteminde PROMPT_COMMANDyeniden hesaplamak için kullanarak başvurmak sürece PS1.
Tonin

1

@Manatwork yanıtını genişleterek, ancak kodunuzu PS1farklı işlevlerde bölmeyi koruyarak , isteminizi aşağıdaki şekilde yazabilirsiniz:

set_exit_code() {
    exit_code=$?
    [[ $exit_code -eq 0 ]] || printf "\[$(tput setaf 1)\] $exit_code \[$(tput sgr0)\] "
}
set_bash_prompt() {
    PS1="$(set_exit_code)$ " # with double quotes!
}
PROMPT_COMMAND=set_bash_prompt

Çift tırnak işaretleri hem ayarlama PS1sırasında hem printfde işlevde kullanılırken zorunludur .


İleride başvurmak için, .bashrckodunuzda bir bash işlevi kullanın - kodu ayrı bir dosyaya koymayın ve çağırın.
starbeamrainbowlabs
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.