Есть ли способ увидеть прогресс tar в каждом файле?
У меня есть пара больших файлов, которые я хотел бы сжать. Я могу сделать это, например, с
tar cvfj big-files.tar.bz2 folder-with-big-files
Проблема в том, что я не вижу никакого прогресса, поэтому я понятия не имею, сколько времени это займет или что-то в этом роде. С помощью v
По крайней мере, я вижу, когда каждый файл готов, но когда файлов мало и они большие, это не самый полезный.
Есть ли способ получить tar, чтобы показать более детальный прогресс? Например, процент выполнения или индикатор выполнения или оставшееся время или что-то еще. Либо для каждого отдельного файла, либо для всех, либо для обоих.
17 ответов
Я предпочитаю oneliners, как это:
tar cf - /folder-with-big-files -P | pv -s $(du -sb /folder-with-big-files | awk '{print $1}') | gzip > big-files.tar.gz
Это будет иметь следующий результат:
4.69GB 0:04:50 [16.3MB/s] [==========================> ] 78% ETA 0:01:21
Для OSX (из ответа Кендзи)
tar cf - /folder-with-big-files -P | pv -s $(($(du -sk /folder-with-big-files | awk '{print $1}') * 1024)) | gzip > big-files.tar.gz
Вы можете использовать PV для достижения этой цели. Чтобы правильно сообщить о прогрессе, pv
Нужно знать, сколько байтов вы выбрасываете. Итак, первым шагом является вычисление размера (в килобайтах). Вы также можете полностью сбросить индикатор выполнения и просто позволить pv
сказать, сколько байтов он видел; это сообщило бы о том, "сделано так много и так быстро".
% SIZE=`du -sk folder-with-big-files | cut -f 1`
А потом:
% tar cvf - folder-with-big-files | pv -p -s ${SIZE}k | \
bzip2 -c > big-files.tar.bz2
Лучше прогресс бар..
apt-get install pv dialog
(pv -n file.tgz | tar xzf - -C target_directory ) \
2>&1 | dialog --gauge "Extracting file..." 6 50
Проверьте --checkpoint
а также --checkpoint-action
опции на странице информации о tar (что касается моего дистрибутива, описание этих опций не содержится на странице man → RTFI).
См. https://www.gnu.org/software/tar/manual/html_section/tar_26.html
С их помощью (и, возможно, с функциональностью, чтобы написать собственную команду контрольной точки), вы можете рассчитать процент...
Вдохновленный ответом помощника
Еще один способ - использовать родной tar
опции
FROMSIZE=`du -sk ${FROMPATH} | cut -f 1`;
CHECKPOINT=`echo ${FROMSIZE}/50 | bc`;
echo "Estimated: [==================================================]";
echo -n "Progess: [";
tar -c --record-size=1K --checkpoint="${CHECKPOINT}" --checkpoint-action="ttyout=>" -f - "${FROMPATH}" | bzip2 > "${TOFILE}";
echo "]"
результат как
Estimated: [==================================================]
Progess: [>>>>>>>>>>>>>>>>>>>>>>>
полный пример здесь
Использование только смолы
tar
имеет опцию (начиная с v1.12) для печати информации о состоянии сигналов с помощью --totals=$SIGNO
Например:
tar --totals=USR1 -czf output.tar input.file
Total bytes written: 6005319680 (5.6GiB, 23MiB/s)
Total bytes written: [...]
информация печатается на каждом сигнале USR1, например:
pkill -SIGUSR1 tar
Источник:
Метод, основанный на tqdm:
tar -v -xf tarfile.tar -C TARGET_DIR | tqdm --total $(tar -tvf tarfile.tar | wc -l) > /dev/null
Вы не увидите, сколько осталось, но вы увидите, что он прогрессирует с очень простым дополнением к вашей команде
--checkpoint=1000
# tar xf file.tar --checkpoint=1000
tar: Read checkpoint 1000
tar: Read checkpoint 2000
tar: Read checkpoint 3000
tar: Read checkpoint 4000
tar: Read checkpoint 5000
tar: Read checkpoint 6000
...
Подробнее на https://www.gnu.org/software/tar/manual/html_section/tar_25.html.
Только что заметил комментарий о MacOS, и хотя я думаю, что решение от @akira (и pv) гораздо точнее, я подумал, что я поймал догадку и быстрый обходной путь в моей коробке MacOS с tar и отправил бы ему сигнал SIGINFO. Как ни странно, это сработало:), если вы работаете в BSD-подобной системе, это должно работать, но на Linux-коробке вам может потребоваться отправить SIGUSR1 и / или tar
может не работать так же.
Недостатком является то, что он предоставит вам только вывод (на стандартный вывод), показывающий, как далеко находится текущий файл, так как я предполагаю, что он понятия не имеет, насколько велик поток данных, который он получает.
Так что да, альтернативный подход - запускать tar и периодически отправлять SIGINFO каждый раз, когда вы хотите узнать, как далеко он продвинулся. Как это сделать?
Специальный ручной подход
Если вы хотите иметь возможность проверять статус на разовой основе, вы можете нажать control-T
(как упомянул Брайан Свифт) в соответствующем окне, которое отправит сигнал SIGINFO. Я полагаю, что проблема в том, что он отправит его всей вашей цепочке, так что если вы делаете:
% tar cvf - folder-with-big-files | bzip2 -c > big-files.tar.bz2
Вы также увидите bzip2 отчет о его статусе вместе с tar:
a folder-with-big-files/big-file.imgload 0.79 cmd: bzip2 13325 running
14 0.27u 1.02s
adding folder-with-big-files/big-file.imgload (17760256 / 32311520)
Это хорошо работает, если вы просто хотите проверить, если это tar
вы бежите, застряли или просто медленно В этом случае вам, вероятно, не нужно слишком беспокоиться о проблемах форматирования, так как это всего лишь быстрая проверка.
Этакий автоматизированный подход
Если вы знаете, что это займет некоторое время, но хотите что-то вроде индикатора прогресса, альтернативой может быть запуск вашего процесса tar, а в другом терминале определить его PID, а затем выбросить его в скрипт, который просто несколько раз посылает сигнал через, Например, если у вас есть следующий скриптлет (и вызовите его, как сказать script.sh PID-to-signal interval-to-signal-at
):
#!/bin/sh
PID=$1
INTERVAL=$2
SIGNAL=29 # excuse the voodoo, bash gets the translation of SIGINFO,
# sh won't..
kill -0 $PID # invoke a quick check to see if the PID is present AND that
# you can access it..
echo "this process is $$, sending signal $SIGNAL to $PID every $INTERVAL s"
while [ $? -eq 0 ]; do
sleep $INTERVAL;
kill -$SIGNAL $PID; # The kill signalling must be the last statement
# or else the $? conditional test won't work
done
echo "PID $PID no longer accessible, tar finished?"
Если вы вызываете его таким образом, так как вы нацеливаетесь только на tar
вы получите более похожий результат
a folder-with-big-files/tinyfile.1
a folder-with-big-files/tinyfile.2
a folder-with-big-files/tinyfile.3
a folder-with-big-files/bigfile.1
adding folder-with-big-files/bigfile.1 (124612 / 94377241)
adding folder-with-big-files/bigfile.1 (723612 / 94377241)
...
что я признаю, это довольно мило.
И последнее, но не менее важное - мои скрипты довольно ржавые, поэтому, если кто-то захочет пойти и почистить / исправить / улучшить код, продолжайте свою жизнь:)
Вдохновленный ответом Ноа Спурриера
function tar {
local bf so
so=${*: -1}
case $(file "$so" | awk '{print$2}') in
XZ) bf=$(xz -lv "$so" |
perl -MPOSIX -ane '$.==11 && print ceil $F[5]/50688') ;;
gzip) bf=$(gzip -l "$so" |
perl -MPOSIX -ane '$.==2 && print ceil $F[1]/50688') ;;
directory) bf=$(find "$so" -type f | xargs du -B512 --apparent-size |
perl -MPOSIX -ane '$bk += $F[0]+1; END {print ceil $bk/100}') ;;
esac
command tar "$@" --blocking-factor=$bf \
--checkpoint-action='ttyout=%u%\r' --checkpoint=1
}
В macOS сначала убедитесь, что у вас есть все доступные команды, и установите недостающие (например, pv
) используя варево.
Если вы только хотите tar
без сжатия, идти с:
tar -c folder-with-big-files | pv -s $[$(du -sk folder-with-big-files | awk '{print $1}') * 1024] > folder-with-big-files.tar
Если вы хотите сжать, перейдите с:
tar cf - folder-with-big-files -P | pv -s $[$(du -sk folder-with-big-files | awk '{print $1}') * 1024] | gzip > folder-with-big-files.tar.gz
Примечание. Может пройти некоторое время, прежде чем появится индикатор выполнения. Попробуйте сначала небольшую папку, чтобы убедиться, что она работает, а затем перейдите к папке с большими файлами.
Для простого извлечения с помощью .
pv mysql.tar.gz | tar -x
Вы получите такой вывод:
249MiB 0:00:19 [14.0MiB/s] [==> ] 10% ETA 0:02:44
Вот оно в действии:
Установитьpv
в macOS просто используйте Homebrew с:
brew install pv
На других системах репозиторий с исходниками можно посмотреть здесь .
Если вы знаете номер файла вместо общего размера всех из них:
альтернатива (менее точная, но подходящая) заключается в использовании опции -l и отправке в канале unix имен файлов вместо содержимого данных.
Давайте поместим 12345 файлов в mydir, команда:
[myhost@myuser mydir]$ tar cfvz ~/mytarfile.tgz .|pv -s 12345 -l > /dev/null
вы можете знать это значение заранее (из-за вашего варианта использования) или использовать какую-то команду, например find+wc, чтобы обнаружить его:
[myhost@myuser mydir]$ find | wc -l
12345
Установите команды диалога и pv с помощью
sudo apt-get install dialog pv
а затем выполните tar вот так
(tar cf - /folder-with-big-files | pv -n -s $(du -sb /folder-with-big-files | awk '{print $1}') | gzip -9 > big-files.tar) 2>&1 | dialog --gauge 'Your backup is in progress...' 7 70
В моем повседневном использовании мне не нужно знать точный процентный уровень прогресса операции, только если она работает и (иногда) насколько она близка к завершению.
Я решаю эту потребность минимально, показывая количество обрабатываемых файлов в отдельной строке; в Bash:
let n=0; tar zcvf files.tgz directory | while read LINE; do printf "\r%d" $((n++)) ; done ; echo
Поскольку я часто использую это, я определил псевдоним функции в.bashrc:
function pvl { declare -i n=0; while read L ; do printf "\r%d" $((++n)) ; done ; echo ; }
Тогда просто:
tar zcvf files.tgz directory | pvl
При необходимости я могу заранее подсчитать количество файлов с помощью
find directory | wc -l
(Или лучше использовать ту же функцию, что и [find directory | pvl
] подавить мое нетерпение!).
Другой пример, установка прав для виртуального сайта (после этого
chown -R
работает быстро, потому что имена файлов находятся в кеше файловой системы):
find /site -print -type d -exec chmod 2750 "{}" \; -o -type f -exec chmod 640 "{}" | pvl
Это правда, что эта боковая обработка может замедлить основную операцию, но я думаю, что печать символа возврата и нескольких цифр не может быть слишком затратной (кроме того, ожидание появления следующего знака равенства или изменения процентной цифры кажется медленным по сравнению с субъективным свечением. скорость смены цифр!).
Если вас устраивает использование 7z:
7z a example.tar example/
Это покажет этап сканирования диска
Scanning the drive:
2608M 139834 Scan example/file.txt
а также некоторую другую полезную информацию для просмотра.
Scanning the drive:
157318 folders, 601997 files, 13683142277 bytes (13 GiB)
Creating archive: example.tar
Items to compress: 759315
3% 29587 + example/file.txt
Вот несколько номеров резервной копии Prometheus (метрических данных) на Debian/buster AMD64:
root# cd /path/to/prometheus/
root# tar -cf - ./metrics | ( pv -p --timer --rate --bytes > prometheus-metrics.tar )
Отменил это задание, так как на диске недостаточно свободного места.
Экспериментируя с zstd
в качестве компрессора для tar
с мониторингом прогресса с помощью pv
:
root# apt-get update
root# apt-get install zstd pv
root# tar -c --zstd -f - ./metrics | ( pv -p --timer --rate --bytes > prometheus-metrics.tar.zst )
10.2GiB 0:11:50 [14.7MiB/s]
root# du -s -h prometheus
62G prometheus
root# du -s -h prometheus-metrics.tar.zst
11G prometheus-metrics.tar.zst