Comment supprimer et remplacer la dernière ligne du terminal en utilisant bash?

Je veux implémenter une barre de progression montrant les secondes écastings en bash. Pour cela, je dois effacer la dernière ligne affichée à l’écran (la commande “clear” efface tout l’écran, mais je dois effacer uniquement la ligne de la barre de progression et la remplacer par la nouvelle information).

Le résultat final devrait ressembler à:

$ Elapsed time 5 seconds 

Ensuite, après 10 secondes, je veux remplacer cette phrase (dans la même position sur l’écran) par:

 $ Elapsed time 15 seconds 

faire écho à un retour chariot avec \ r

 seq 1 1000000 | while read i; do echo -en "\r$i"; done 

de l’homme echo:

 -n do not output the trailing newline -e enable interpretation of backslash escapes \r carriage return 

Le retour chariot ne fait que déplacer le curseur au début de la ligne. Ce n’est pas grave si chaque nouvelle ligne de sortie est au moins aussi longue que la précédente, mais si la nouvelle ligne est plus courte, la ligne précédente ne sera pas complètement remplacée, par exemple:

 $ echo -e "abcdefghijklmnopqrstuvwxyz\r0123456789" 0123456789klmnopqrstuvwxyz 

Pour effacer la ligne du nouveau texte, vous pouvez append \033[K après le \r :

 $ echo -e "abcdefghijklmnopqrstuvwxyz\r\033[K0123456789" 0123456789 

http://en.wikipedia.org/wiki/ANSI_escape_code

La réponse de Derek Veit fonctionne bien tant que la longueur de la ligne ne dépasse jamais la largeur du terminal. Si ce n’est pas le cas, le code suivant empêchera la sortie indésirable:

avant que la ligne soit écrite pour la première fois, faire

 tput sc 

qui enregistre la position actuelle du curseur. Maintenant, chaque fois que vous voulez imprimer votre ligne, utilisez

 tput rc tput ed echo "your stuff here" 

pour revenir à la position du curseur enregistrée, effacez l’écran du curseur vers le bas et écrivez la sortie.

La méthode \ 033 n’a pas fonctionné pour moi. La méthode \ r fonctionne, mais elle n’efface rien, place simplement le curseur au début de la ligne. Donc, si la nouvelle chaîne est plus courte que l’ancienne, vous pouvez voir le texte restant à la fin de la ligne. En fin de compte, le tput était la meilleure solution. Il a d’autres utilisations que le curseur, et il est préinstallé dans de nombreuses dissortingbutions Linux et BSD. Il devrait donc être disponible pour la plupart des utilisateurs.

 #/bin/bash tput sc # save cursor printf "Something that I made up for this ssortingng" sleep 1 tput rc;tput el # rc = restore cursor, el = erase to end of line printf "Another message for testing" sleep 1 tput rc;tput el printf "Yet another one" sleep 1 tput rc;tput el 

Voici un petit script de compte à rebours avec lequel jouer:

 #!/bin/bash timeout () { tput sc time=$1; while [ $time -ge 0 ]; do tput rc; tput el printf "$2" $time ((time--)) sleep 1 done tput rc; tput ed; } timeout 10 "Self-destructing in %s" 

Utilisez le caractère de retour chariot:

 echo -e "Foo\rBar" # Will print "Bar" 

Si la sortie de la progression est multi-lignes ou si le script a déjà imprimé le nouveau caractère de ligne, vous pouvez sauter avec une ligne comme:

printf "\033[5A"

ce qui fera passer le curseur de 5 lignes. Ensuite, vous pouvez écraser tout ce dont vous avez besoin.

Si cela ne fonctionne pas, vous pouvez essayer printf "\e[5A" ou echo -e "\033[5A" , ce qui devrait avoir le même effet.

Fondamentalement, avec les séquences d’échappement, vous pouvez contrôler presque tout dans l’écran.

Le moyen le plus simple est d’utiliser le caractère que je suppose.

L’inconvénient est que vous ne pouvez pas avoir de lignes complètes, car cela efface uniquement la ligne actuelle.

Exemple simple:

 time=5 echo -n "Elapsed $time seconds" sleep 10 time=15 echo -n "Elapsed $time seconds" echo "\nDone"