Kaydırma alanından tasarruf etmek için bash'daki eski bilgi istem satırlarını temizle


11

Terminal temam eskiden böyle,

onları daha önce terminal haline getir

Ama istemin çok fazla yer harcadığını düşündüm. Ve sonra her komut çalıştırışımda istemi temizleyebileceğim konusunda bir fikrim var. Ben bash kullanıyordum, çözümlerden biri preexec_invoke_execişlevi kullanmak .

Son komut satırlarını temizlemek için aşağıdaki komutu kullanıyorum:

echo -ne "\033[1A\033[K\033[1A\033[K\033[31;1m$ \033[0m"

Böylece terminal çok temiz, böyle,

resim açıklamasını buraya girin

Ama şimdi benim sorunum, bir satırda çoklu komutları kullanmak istediğimde , örneğin, kullandığımda sorun olacak for i in ....

İşte .bashrc'deki işlevin tam sürümü,

preexec () { echo -ne "\033[1A\033[K\033[1A\033[K\033[31;1m$ \033[0m"; echo -n "$1"; echo -ne "  \033[37;2m["; echo -n "$2"; echo -ne "]\033[0m\n"; }
preexec_invoke_exec () {
    [ -n "$COMP_LINE" ] && return  # do nothing if completing
    [ "$BASH_COMMAND" = "$PROMPT_COMMAND" ] && return # don't cause a preexec for $PROMPT_COMMAND
    local this_command=`history 1 | sed -e "s/^[ ]*[0-9]*[ ]*//g"`;
    local this_pwd=`pwd`; 
    preexec "$this_command" "$this_pwd"
}
trap 'preexec_invoke_exec' DEBUG

Glif Lefkowitz zsh - güzel!

2
Kolay çözüm zsh... ile başlar
Gilles 'SO- kötü olmayı bırak'

Sorunuzu orada kaçırdım ...
David Hoelzer

@DavidHoelzer İşlevi for i in $(seq 1 10); do ls; doneile yaparsanız , yineleme komutlarının çıktısı tabiri caizse "yutulur". Bu yüzden OP bu istemi etkinleştirirken davranışı sterilize etmek istedi. Bunu desteklememin sebebi kabukta farkındalık, kullanılabilirlik, geri bildirim ve taşınabilirlik konusuna ilgi. Önceki yorumuma koyduğum bağlantı, süper kullanıcıdaki gönderiye yol açıyor - bu snippet'i ilişkilendirme sorununa gittiler, bu yüzden bir tuzak işlevi şeklinde yerel zsh işlevselliğini (ki ilginç olduğunu düşünüyorum) taklit eden bir prototip buraya.

Yanıtlar:


3

Birincisinin preexec_invoke_execbirden çok yürütülmesini önlemek için değiştirilmelidir preexec. Ayrıca, preexecgerçek satır sayısını dikkate almak için değiştirin $PS1:

preexec () { 
    # delete old prompt; one "\e[1A\e[K" per line of $PS1
    for (( i=0, l=$(echo -e $PS1 | wc -l) ; i < l ; i++ ))
    do             
        echo -ne "\e[1A\e[K"
    done
    # replacement for prompt
    echo -ne "\e[31;1m$ \e[0m"
    echo -n "$1"
    echo -ne "  \e[37;2m["
    echo -n "$2"
    echo -e "]\e[0m"
}

preexec_invoke_exec () {
    [ -n "$DONTCLEANPROMPT" ] && return
    DONTCLEANPROMPT=x
    [ -n "$COMP_LINE" ] && return  # do nothing if completing
    [ "$BASH_COMMAND" = "$PROMPT_COMMAND" ] && return # don't cause a preexec for $PROMPT_COMMAND
    local this_command=`history 1 | sed -e "s/^[ ]*[0-9]*[ ]*//g"`;
    local this_pwd=`pwd`
    preexec "$this_command" "$this_pwd"
}

trap 'preexec_invoke_exec' DEBUG

PROMPT_COMMAND='unset DONTCLEANPROMPT'

İçin için preexectekrar çalıştırılmak üzere, DONTCLEANPROMPTya ayarlanmazsa veya ayarlı olması gerekir ''. Bu, PROMPT_COMMANDbirincil bilgi isteminden hemen önce çalıştırılan ile yapılır . Bu nedenle preexec, her komut satırı için yalnızca bir kez çalıştırılır.


Çözümünüz sorunu fordöngü ile çözüyor ! Teşekkür ederim! Başka bir rahatsızlık daha var. Ne olur bunu yaparsanız olmasıdır lskomuta ve çıkışı, o zaman başka yok ls, size nasıl çözmek için bir fikrin var mı ... önce çıktının son satırında silinir alır göreceksiniz?

1
Muhtemelen yalnızca tek bir satır içeren bir bilgi istemi kullanıyorsunuz. prexecYazdırılacak ilk yankıyı iki yerine değiştirin ( "\033[1A\033[K\033[31;1m$ \033[0m"yalnızca \033[1A\033[K1 satır yukarı taşı, satır sonuna kadar sil).
Adaephon

Kusursuz! Çözümünüz ve açıklamak için zaman ayırdığınız için çok teşekkür ederim. Bu OP'nin problemini çözer ve çözümü daha da ayıklar. Herkes için kullanılabilir hale getirir! Şerefe!
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.