XTerm'i alttaki komut istemiyle nasıl başlatabilirim?


12

XTerm'i başlatırken komut istemi terminalin ilk satırında başlar. Komutları çalıştırdığınızda, komut istemi alta gelene kadar aşağı hareket eder ve bundan sonra orada kalır (hatta değil Shift- Page Downveya fare bunu değiştirebilir). Terminal ömrünün başlangıcı "özel" olmak yerine , istem her zaman terminalin altında olmalıdır. Çok satırlı bir istemim olduğunu lütfen unutmayın .

Elbette, daha önce olduğu gibi çalışmalıdır (yeniden boyutlandırılabilir, kaydırılabilir, çıktıda gereksiz satırlar olmamalı ve çıkış gizemli bir şekilde kaybolmamalıdır), bu yüzden PROMPT_COMMAND='echo;echo;...'veya benzeri bir seçenek değildir. Çözelti ideal olarak kabuğa özgü olmamalıdır.

Düzenleme: Geçerli çözüm basit durumlarda çalışırken, bazı sorunlar vardır:

  • Bu var Bash özgü . İdeal bir çözüm diğer kabuklara taşınabilir olmalıdır.
  • Bu diğer işlemler değiştirirseniz başarısızPS1 . Bir örnek ekler Virtualenv olduğu (virtualenv)en başından ait PS1sonra her zaman sadece ekranın üst kısmında kaybolur.
  • Ctrl- lartık tarihin son sayfasını kaldırıyor .

Bu sorunlardan kaçınmanın bir yolu var mı?


Her nasılsa, Xterm'in kaydırma çubuğu arabelleğine boş karakterler eklememiz gerekiyor.
SHW

3
Aslında, komut komutu kullanılarak bilgi istemi herhangi bir zamanda kolayca tekrar en üste taşınabilir clear.
werediver

@SHW Bunun için bir kesmek yerine bir ayar olmasını umuyordum. Terminal hack'leri benim deneyimime çok ince hatalar getirme eğilimindedir.
l0b0

@werediver Ama asla zirvede olmasını istemiyorum.
l0b0

1
Yalnızca kabuk bir istemin ne zaman çıktı verdiğini bildiğinden, herhangi bir çözüm kabuğun bağlamında olmalıdır. XTerm'i çatallamak bile yardımcı olmaz çünkü XTerm çıktısının istenmesinin bir istem olup olmadığını bilmiyor. Terminal için, kabuk istemi sadece alabileceği başka bir karakter dizisinden farklı olmayan başka bir karakter dizisidir.
celtschk

Yanıtlar:


11

Kullanıyorsanız bash, aşağıdakileri yapmalısınız:

TOLASTLINE=$(tput cup "$LINES")
PS1="\[$TOLASTLINE\]$PS1"

Veya ( tputher komut isteminden önce bir komut çalıştırdığından daha az verimlidir , ancak terminal penceresi yeniden boyutlandırıldıktan sonra çalışır):

PS1='\[$(tput cup "$LINES")\]'$PS1

tputÇıkış kodunun değiştirilmesini önlemek için , kodu açıkça kaydedip sıfırlayabilirsiniz:

PS1='\[$(retval=$?;tput cup "$LINES";exit $retval)\]'$PS1

Değişkenin retvalyerel olduğunu unutmayın ; retvalkabukta başka türlü tanımlamış olabileceğiniz herhangi bir değişkeni etkilemez .

Çoğu terminal cupözelliği aynı olduğundan \e[y;xH, onu da kodlayabilirsiniz:

PS1='\[\e[$LINES;1H\]'$PS1

PS1'in daha sonra sıfırlanmasına karşı güvenli olmasını istiyorsanız, PROMPT_COMMANDdeğişkeni de kullanabilirsiniz . Ayarlanırsa, bilgi istemi çıkmadan önce komut olarak çalıştırılır . Böylece etki şu şekilde de elde edilebilir:

PROMPT_COMMAND='(retval=$?;tput cup "$LINES";exit $retval)'

Elbette, sıfırlama PS1bunu etkilemezken, diğer bazı yazılımlar da değişebilir PROMPT_COMMAND.


Nasıl tputbirçok farklı echokomutlar? (Merak etme)
SHW

@ l0b0, muhtemelen ayrı bir cevabı hak etmiyor. Umarım celtschk cevabını düzenlediğime aldırmaz.
Stéphane Chazelas

'\[$(tput cup "$LINES")\]' güzel çalışıyor . Teşekkürler!
l0b0

Şununla ilgili bir sorun var tput: Sıfırlanıyor gibi görünüyor $exit_code. Kullanarak düzeltildi\[\e[$LINES;1H\] .
l0b0

1
@ l0b0: Artık tputçıkış kodunu koruyan bir sürüm ekledim .
celtschk

4

Önceki cevaba hafif bir sadeleştirme olarak, sadece çalıştırmayı daha kolay buldum:

tput cup $LINES

başında .bashrcveya .zshrc. Sadece işi yapar.

Artıları:

  • sadece bir kez yazdırır, kabuğunuzu başlattığınızda

Eksileri:

  • ^ L ile ekrana temizlerken bunu Yazdırılmazsa ve aliasing yok clearetmek clear; tput ...yardım etmez;
  • istemi, terminal yeniden boyutlandırıldığında başka bir yere taşınır

2

Cevaplar $LINESgereksiz yere taşınabilir değildir. Yapıldığı gibi , konumu keyfi olarak büyük bir satır numarasına ayarlamayı resizeisteyebilirsiniz xterm, ör.

tput cup 9999 0

(10 bin satırdan daha küçük bir pencereniz olduğunu varsayarsak, geri kaydırma dikkate alınmaz ).

Dize, pencereyi yeniden boyutlandırmanın bir yan etkisi olarak değişmeyeceğinden, bunu bir kez hesaplayabilir ve komut istemi dizenize sabit olarak yapıştırabilirsiniz;

TPUT_END=$(tput cup 9999 0)

ve sonra

PS1="${TPUT_END} myprompt: "

tercihlerinize göre.

Değiştirilen diğer süreçlere gelince PS1: istediğiniz PS1gibi görünmesini sağlamak için bu değişikliklerden sonra yeniden hesaplamanız gerekir . Ancak soruda , değişikliklerin nerede yapılacağını göstermek için yeterli ayrıntı yok .

Ve son olarak: sekmeyi tamamlama davranışı, bash'ın varsayımları nedeniyle bu tür bir değişiklikle örtüşmüyor.


"Sekme tamamlama davranışı bu tür bir değişiklikle örtüşmüyor" ile ne demek istiyorsun?
l0b0

Sanırım demek istedin PS1="${TPUT_END} myprompt: ", hattaPS1="${TPUT_END}${PS1}"
l0b0

İkincisi için - sağ (makefiles düşüncesinden yazım hatası). Öncelikle, bash'ın komut düzenlemesinin satırı (istemi ile) yeniden basabilmesine bağlı olduğunu ve komutun tamamlanması nedeniyle kaydırma ile birleştiğinde garip bir davranış elde edebileceğinizi aklımda tutuyorum.
Thomas Dickey
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.