Oui, c'est très possible.
En supposant que votre code existant (en fonction de vos messages précédents) va actuellement quelque chose comme ceci:
do_something() {
...
echo -ne "\r$index of $No_of_Files Completed"
...
}
do_something A &
do_something B &
do_something C &
wait
... vous pouvez alors effectuer les réglages suivants afin d'obtenir l'effet que vous aviez en tête :
# Background tasks will no longer write directly to the console; instead,
# they will write to temporary files which will be read periodically
# by a special log printer task (which will display everything nicely.)
#
# Name of temporary files
STATUS_BASENAME="/tmp/~$$.status"
# Process IDs of backgrounded tasks; we record them so we can wait on them
# specifically but not wait on the special log printer task
TASK_PIDS=""
do_something() {
# First parameter must be a task ID starting at 0 incremented by 1
TASK_ID=$1 ; shift
...
# We write new status to status file (note we don't echo -n, we want that
# trailing newline)
# Try to go through a temporary status file which we rename afterwards to
# avoid race conditions with the special log printer task
echo "$x of 5 Completed" >"${STATUS_BASENAME}.${TASK_ID}.tmp"
mv "${STATUS_BASENAME}.${TASK_ID}.tmp" "${STATUS_BASENAME}.${TASK_ID}"
...
}
# Special log printer task
status_printer() {
# First time in the loop is special insofar we don't have to
# scroll up to overwrite previous output.
FIRST_TIME=1
while true ; do
# If not first time, scroll up as many lines as we have
# regular background tasks to overwrite previous output.
test $FIRST_TIME -eq 0 && for PID in $TASK_PIDS ; do
echo -ne '\033M' # scrol up one line using ANSI/VT100 cursor control sequences
done
FIRST_TIME=0
TASK_ID=0
for PID in $TASK_PIDS ; do
# If status file exists print first line
test -f "${STATUS_BASENAME}.${TASK_ID}" && head -1 "${STATUS_BASENAME}.${TASK_ID}" || echo "waiting..."
TASK_ID=`expr $TASK_ID + 1` # using expr for portability :)
done
test -f "${STATUS_BASENAME}.done" && return
sleep 1 # seconds to wait between updates
done
}
do_something 0 A &
TASK_PIDS="$TASK_PIDS $!"
do_something 1 B &
TASK_PIDS="$TASK_PIDS $!"
do_something 2 C &
TASK_PIDS="$TASK_PIDS $!"
status_printer &
PRINTER_PID=$!
# Wait for background tasks
wait $TASK_PIDS
# Stop special printer task instead of doing just
# kill $PRINTER_PID >/dev/null
touch "${STATUS_BASENAME}.done"
wait $PRINTER_PID
# Cleanup
rm -f "${STATUS_BASENAME}."*
est-il possible avec printf instructions dans shell avec différents caractères d'échappement \ n \ r etc ?? – Kiran
Pas vraiment. Comment empêchez-vous les deux threads d'écrire au terminal en même temps et de déconner les lignes? Et vous devez utiliser les échappements ANSI pour définir la position du curseur * en haut * d'une ligne. – ephemient
Ya éphémère, c'est ce que je regarde. Si c'est possible en utilisant le script shell seul .. Je sais, je m'attends trop .. Serait bien si je pouvais le faire .. – Kiran