Afficher le temps écoulé chaque seconde en exécutant un script bash

J’exécute un script shell sous Linux Mint qui appelle certains processus en quelques minutes. Pour chaque processus, je veux faire écho à un message comme celui-ci:

echo "Cleaning temporary files... X seconds." myprocess 

où X est le temps écoulé actuel et je voudrais qu’il change toutes les secondes, mais sans imprimer une nouvelle ligne.

Y a-t-il un bon moyen de le faire? Je n’ai trouvé que des moyens d’imprimer le temps total à la fin, mais pas le temps écoulé pendant l’exécution du processus.

Utilisez ceci au début de votre script, cela crée un sous-processus qui s’exécute en arrière-plan et continue à mettre à jour le statut.

 file=$(mktemp) progress() { pc=0; while [ -e $file ] do echo -ne "$pc sec\033[0K\r" sleep 1 ((pc++)) done } progress & #Do all the necessary staff #now when everything is done rm -f $file 

Vous pouvez exécuter chaque commande avec le temps:

 time  

puis utilisez sed / awk pour calculer le temps écoulé.

Vous devrez exécuter le processus en arrière-plan avec & , sinon le rest du script attendra qu’il se termine. Utilisez les backspaces pour remplacer votre ligne actuelle . Assurez-vous donc de ne pas utiliser de nouvelles lignes.

Alors, pour faire ce que vous voulez:

 myproc & myPid=$! # save process id tmp="" while true; do if kill -0 "$myPid"; then # if the process accepts a signal, keep waiting for i in {0..${#tmp}..1}; do printf "%b" "\b" # print backspaces until we have cleared the previous line done tmp=$( printf "Cleaning temp files... %t seconds." ) printf "%s" "$tmp" else break # drop out of the while loop fi sleep 1 done 

Voici un moyen d’avoir awk print sur STDERR toutes les secondes. Vous devez simplement append:

  • A la fin de mon processus, créez un fichier / tmp / SOMETHING
  • avoir awk inclure un test: il se termine quand / tmp / SOMETHING apparaît

La partie boucle (sans le test de terminaison … donc “boucle infinie” jusqu’à ce que CTRL-C) soit:

  ping 127.0.0.1 | awk ' BEGIN{cmd="date +%s"; cmd|getline startup ; close (cmd) } /bytes from/ { cmd | getline D ; close (cmd) ; print D-startup | "cat >&2" }' 

il suffit maintenant d’utiliser “printf” et la séquence d’échappement ansi pour imprimer sans nouvelle ligne, faire revenir ansi-escape au début du numéro et vider la sortie (tous les descripteurs) en appelant le système:

  ping 127.0.0.1 | awk -v getback4char="$(printf '\033[4D')" ' BEGIN{cmd="date +%s"; cmd|getline startup ; close (cmd) ; printf "Elapsed time: ";} /bytes from/ { cmd | getline D ; close (cmd) ; printf "%4d%s" ,(D-startup) , getback4char | "cat >&2" system("") }' 

note: ceci est compatible avec toutes les versions de awk que je connais, même celles qui sont ANCIENTES (c.-à-d. pas seulement gawk / nawk seulement, mais aussi le vénérable awk.)