Индикатор выполнения для отображения прогресса в зависимости от количества файлов, найденных/завершенных в цикле for?

A veces, los permisos pueden ser un problema :si uno de los archivos de configuración en su directorio de inicio ha terminado siendo propiedad de la raíz, entonces la sesión no puede guardarse cuando se cierra.

Creo que find. -user root, ejecutar desde su directorio de inicio puede encontrar problemas como este.

1
07.06.2019, 22:24
3 ответа

Я предлагаю два варианта

1. bashСценарий оболочки, использующий pvдля непрерывного отображения прогресса

Установитьpv

sudo apt install pv  # in Debian and Ubuntu, other commands in other distros

Шеллскрипт с демонстрационной программой

#!/bin/bash

# if only files (if directories, you may need another command)

cnt=0
for i in dir/*
do
 cnt=$((cnt+1))
done
files="$cnt"
> log
> err
for i in dir/*
do
 ls "$i" >> log 2>> err  # simulating the actual process
 sleep 2                 # simulating the actual process
 echo "$i"
done | pv -l -s "$files" > /dev/null  # progress view using lines with $i

Демо

В процессе

$./pver
2.00  0:00:06 [0,00 /s] [===============>                        ] 40% ETA 0:00:09

После финиша

$./pver
5.00  0:00:10 [ 499m/s] [======================================>] 100%

2. bashСценарий оболочки для отображения текущего состояния выполнения по запросу

  • forцикл в фоновом режиме, запустить programи счетчикcnt
  • whileцикл ищет ввод символа (если c, то расскажите о прогрессе)

Индикатора выполнения нет, но в любое время вы можете получить обновление статуса о ходе выполнения.

Шеллскрипт с демонстрационной программой

#!/bin/bash

cnt=0
echo "0" > clog

program () {

ls "$1"
sleep 5
}

# main

files=$(ls -1 dir|wc -l)

for i in dir/*
do
    program "$i"
    cnt=$((cnt+1))
    echo "$cnt" > clog
done > log &

while [ "$cnt" != "$files" ]
do
 cnt=$(cat clog)
 read -sn1 -t1 chr
 if [ "$chr" == "c" ]
 then
  echo "$cnt of $files files processed; running..."
 fi
done
echo "$cnt of $files files processed; finished :-)"

Демо

$./loop
0 of 5 files processed; running...
3 of 5 files processed; running...
5 of 5 files processed; finished :-)

$ cat log
dir/file1
dir/file2
dir/file3
dir/file4
dir/file w space
1
27.01.2020, 23:18

Я предлагаю сохранить строку для индикатора выполнения, заполнить ее каким-либо символом для каждого файла и заменить их другим во время вашего цикла:

bar=""; for i in *.EXT; do bar=$bar-; done; for i in *.EXT; do PROGRAM OPTION1 OPTION2 "$i"; bar=${bar/-/=}; printf "%s\r" $bar; done

Но поскольку ваш ffmpegвыдает результат, он будет мешать печати индикатора выполнения. Вы можете перенаправить вывод на /dev/null, чтобы вообще его не видеть, но может быть полезно знать, если что-то пошло не так, поэтому я предлагаю перенаправить его в файлы журнала для stdoutи stderr, на этот раз напечатанные как многострочный -скрипт, чтобы сделать его более читабельным:

mkdir -p hflip 
bar=""
for i in *.mp4; do
  bar=$bar-
done
for i in *.mp4; do
  ffmpeg -n -i "$i" -vf hflip -c:a copy hflip/"${i%.*}.mp4" > /tmp/log.out 2> /tmp/log.err
  bar=${bar/-/=}
  printf "%s\r" $bar
done
more /tmp/log.err

Отобразится журнал со всеми ошибками после обработки файлов. Вы также можете отобразить log.out, но поскольку речь идет о ffmpeg, он любит выводить много вещей, которые большинство людей не хотят читать. (-;

2
27.01.2020, 23:18

Попробуйте что-то подобное для простого решения (вам нужен пакет tqdm ):

for i in *.EXT; do PROGRAM OPTION1 OPTION2 "$(echo $i|tqdm)"; done

при условии, что в ваших именах файлов нет "забавных" символов.

1
27.01.2020, 23:18

Теги

Похожие вопросы