Чи є спосіб побачити будь-який прогрес на файл на файл?


122

У мене є кілька великих файлів, які я хотів би стиснути. Я можу це зробити, наприклад

tar cvfj big-files.tar.bz2 folder-with-big-files

Проблема полягає в тому, що я не бачу жодного прогресу, тому я не маю уявлення, скільки часу це займе чи щось подібне. Використовуючи, vя можу принаймні побачити, коли кожен файл завершений, але коли файлів мало і великих, це не є найбільш корисним.

Чи є спосіб отримати дьоготь, щоб показати більш детальний прогрес? На кшталт відсотка, зробленого або смужки прогресу, передбачуваного часу або щось. Або для кожного окремого файлу, або для всіх, або для обох.

Відповіді:


100

Я віддаю перевагу такій лінії, як це:

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

2
На OSX du не приймає -b аргумент, необхідний для резервного копіювання до: $ ((du -sk / folder-with | awk '{print $ 1}' * * 1024))
1313

4
Приємно, один лайнер. Чи можете ви це пояснити? Або це просто магічно спрацьовує якось?
Кіссакі

2
Гаразд, у мене цеpv $FILE.tgz | tar xzf - -C $DEST_DIR
Krzysztof Szewczyk

1
Для OS X мені потрібно було використовувати форму квадратних дужок для арифметичного розширення, завдяки чому: tar cf - /folder-with-big-files -P | pv -s $[$(du -sk /folder-with-big-files | awk '{print $1}') * 1024] | gzip > big-files.tar.gzБез цієї зміни я отримував-bash: syntax error near unexpected token ')'
Дін Бекер

1
Зауважте, що прогрес не відображається до тих пір, поки команда du не закінчиться, що може зайняти деякий час, залежно від розміру, складності та фрагментації каталогу.
Rooster242

75

Ви можете використовувати 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

Класно. pvСхоже, не йде з Mac OS X, але я спробую це випробувати, як тільки у мене буде комп'ютер із MacPorts. Чи можете ви пояснити, що ви там робите? Не зовсім впевнений, що саме робить перший рядок.
Свиш

4
перший рядок: отримання інформації про те, скільки байтів буде оброблено другий рядок: використовуйте розмір з першого рядка, щоб дозволити pv відображати "прогрес". оскільки ви переносите дані, pv не знає, скільки ще буде байтів.
акіра

Одне доповнення: SIZE=$(($SIZE * 1000 / 1024))- Я не знаю, чи це вигадка на моїй конкретній платформі, тому я не додаю її у відповідь: duповертає розмір, де 1 kb = 1024 байт, хоча, pvздається, очікує 1 kb = 1000 байт (Я на Ubuntu 10.04)
Ізката

2
@lzkata ви завжди можете попросити duскористатись уподобаним розміром, наприклад du -s --block-size=1000, або просто працювати з простими байтами, наприклад, відмовитись kвід duі pvвикликів. Тим не менш, я б очікував використання обох, 1024якщо не сказано інше, наприклад, наприклад, --siувімкнути du.
Леголас

1
або просто киньте k-речі та просто використовуйте звичайні байти ( du -sbі pv -sбез будь-якого модифікатора). це повинно закінчити всю плутанину.
акіра

22

краща панель прогресу ..

apt-get install pv dialog

(pv -n file.tgz | tar xzf - -C target_directory ) \
2>&1 | dialog --gauge "Extracting file..." 6 50

введіть тут опис зображення


2
Це твори для видобутку, але все-таки потрібно виконати одну зі складніших команд для створення (що було початковим питанням). Це все ще можна поєднувати з тими; це просто складніше.
Даніель Н

17

Ознайомтеся з параметрами --checkpointта --checkpoint-actionпараметрами на сторінці інформації про дьоготь (що стосується мого розповсюдження, опис цих параметрів не міститься на довільній сторінці → RTFI).

Дивіться https://www.gnu.org/software/tar/manual/html_section/tar_26.html

За допомогою цих (і, можливо, функціональних можливостей написати власну команду контрольної точки) ви можете розрахувати відсоток ...


3
Це має бути правильна відповідь. Інші лише пояснюють додаткові інструменти (крім встановлених за замовчуванням, крім того), щоб досягти чогось подібного.
Carmine Giangregorio

@Sardathrion Можливо тому, що це tarспецифічно для GNU .
phk

11

Натхненний відповіддю помічника

Ще один спосіб - це використання нативних 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:   [>>>>>>>>>>>>>>>>>>>>>>>

повний приклад тут


4

Використовуючи лише дьоготь

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

Джерело:


3

Щойно помітив коментар щодо MacOS, і, хоча я думаю, що рішення від @akira (і pv) набагато акуратніше, я подумав, що переслідую хитру і швидку ситуацію в моєму вікні MacOS з дьогтем і надсилаю йому сигнал SIGINFO. Як не дивно, що це спрацювало :) якщо ви працюєте з системою, схожою на BSD, це має працювати, але у вікні Linux вам може знадобитися надіслати SIGUSR1 та / або tarне працювати так само.

Нижня сторона полягає в тому, що вона надасть вам лише вихід (у stdout), який показує вам, наскільки далеко проходить поточний файл, оскільки я здогадуюсь, він не має поняття про те, наскільки великий потік даних він отримує.

Отже, так, альтернативним підходом було б розпалювати дьоготь і періодично надсилати його СІГІНФО в будь-який час, коли ви хочете дізнатися, наскільки він дійшов. Як це зробити?

Спеціальний, ручний підхід

Якщо ви хочете мати можливість перевірити стан на спеціальній основі, ви можете натиснути control-T(як згадував Брайан Свіфт) у відповідне вікно, яке надішле сигнал SIGINFO поперек. Одне питання з цим полягає в тому, що я надішлю його на весь ваш ланцюг, я вважаю, тож якщо ви це робите:

% tar cvf - folder-with-big-files | bzip2 -c > big-files.tar.bz2

Ви також побачите звіт про bzip2 про його статус разом із дьогтем:

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ви, чи просто повільний. Можливо, вам не потрібно надто турбуватися про проблеми форматування в цьому випадку, оскільки це лише швидка перевірка.

Вид автоматизованого підходу

Якщо ви знаєте, що це займе певний час, але ви хочете щось на зразок індикатора прогресу, альтернативою може бути звільнення вашого тарного процесу, а в іншому терміналі розробити його 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)
...

що я визнаю, це свого роду досить.

І останнє, але не менш важливе - мої сценарії начебто іржаві, тому якщо хтось захоче зайти і почистити / виправити / покращити код, продовжуйте своє життя :)


2
Якщо ви працюєте tarв командному рядку, набравши текст, control-Tвін надішле йому SIGINFO. Якби це було за сценарієм, це було б зроблено зkill -INFO pid
Брайаном Свіфтом

Повністю забув control-T, я, звичайно, звик спамувати занадто багато консольних вікон для власного блага ..
tanantish

1
чому я не можу побачити -SIGINFO, коли я роблюkill -l
Феліпе Альварес,

2

Натхненний відповіддю Ноя Спрір'є

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
}

Джерело


17
Можливо, трохи контексту та пояснень?
Кіссакі

1

Якщо вам відомий номер файлу, а не загальний розмір усіх:

альтернативою (менш точною, але підходящою) є використання параметра -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

Отже, чому б не поставити цю команду в підкоманду? =)
Кірбі

tar cfvz ~/mytarfile.tgz . | pv -s $(find . | wc -l) -l > /dev/null. Це працює на вас?
Кірбі

1

Метод, заснований на tqdm :

tar -v -xf tarfile.tar -C TARGET_DIR | tqdm --total $(tar -tvf tarfile.tar | wc -l) > /dev/null

1

На macOS спочатку переконайтеся, що у вас є всі команди, і встановіть відсутні (наприклад pv), використовуючи brew .

Якщо ви хочете лише 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

Примітка. Перш ніж з'явиться панель прогресу, може пройти деякий час. Спробуйте спочатку меншу папку, щоб переконатися, що вона працює, а потім перейдіть до папки з великими файлами.


0

Ось декілька номерів резервної копії 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.