Borre las líneas de aviso antiguas en bash para ahorrar espacio de desplazamiento

11

Mi tema terminal solía ser así,

terminarlos antes

Pero pensé que el aviso desperdiciaba mucho espacio. Y luego tuve la idea de que podía limpiar el mensaje cada vez que ejecutaba un comando. Estaba usando bash, una de las soluciones es usar la preexec_invoke_execfunción.

Uso el siguiente comando para limpiar los últimos caracteres de solicitud:

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

Para que la terminal esté muy limpia, así,

ingrese la descripción de la imagen aquí

Pero ahora mi problema es que habrá un problema si quiero usar comandos múltiples en una línea , digamos, cuando lo use for i in ....

Aquí está la versión completa de la función en mi .bashrc,

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
Libin Wen
fuente
El truco Glyph Lefkowitz zsh : ¡genial!
2
La solución fácil comienza con zsh...
Gilles 'SO- deja de ser malvado'
Me perdí tu pregunta allí ...
David Hoelzer
@DavidHoelzer Bueno, si lo hace for i in $(seq 1 10); do ls; donecon su función, la salida de los comandos iterativos se "traga", por así decirlo. Por lo tanto, OP quería desinfectar el comportamiento mientras habilitaba ese aviso. La razón por la que apoyo esto es el interés por la conciencia en el shell, la usabilidad, la retroalimentación y la portabilidad. El enlace que había puesto en mi comentario anterior conduce a la publicación en superusuario: se tomaron la molestia de atribuir este fragmento, por lo que es un prototipo que emula la funcionalidad nativa de zsh (que creo que es interesante), en forma de una función de captura aquí.

Respuestas:

3

Primero preexec_invoke_exectiene que modificarse para evitar múltiples ejecuciones de preexec. Además, modifique preexecpara tener en cuenta el número real de líneas en $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'

Para preexecpoder ejecutarse nuevamente, DONTCLEANPROMPTdebe estar desarmado o configurado en ''. Esto se hace con PROMPT_COMMAND, que se ejecuta justo antes de que se emita la solicitud principal. Por preexeclo tanto , se ejecutará una vez y solo una vez para cada línea de comando.

Adaephon
fuente
¡Su solución resuelve el problema con el forbucle! ¡Gracias! Hay otro inconveniente. Lo que sucede es que si lo hace lsen el comando y tiene la salida, luego hace otra ls, verá que la última línea de la salida anterior se borra ... ¿Tiene una idea de cómo resolver eso?
1
Probablemente esté utilizando un indicador con una sola línea. Cambie el primer eco prexecpara imprimir "\033[1A\033[K\033[31;1m$ \033[0m", que es solo uno \033[1A\033[K(mover 1 línea hacia arriba, eliminar hasta el final de la línea) en lugar de dos.
Adaephon
¡Perfecto! Muchas gracias por su solución y por tomarse el tiempo para explicarlo. Esto resuelve el problema de OP y depura la solución aún más. ¡Lo hace usable para todos! ¡Salud!