Песочные часы/прогресс при извлечении большого файла с удаленного хоста в оболочке

В общем, нет лучшего решения, чем то, что дано в Базовое управление заданиями :остановить задание, добавить задание в стек и `fg `, но, как вы указываете, это не удается при использовании с &&(, потому что команда, размещенная в фоновом режиме, «выходит» с не -нулевым кодом состояния ), и в любом случае не всегда будет иметь желаемый эффект с составными командами (текущий -работающая команда помещается в фоновый режим, а следующие команды выполняются немедленно ).

Для этого конкретного случая использования -есть решение — вы можете использоватьlockf.pyДиомидиса Спинеллиса для создания очереди команд, ожидающих завершения текущей aptкоманды:

lockf /var/lib/apt/lock apt install tree

Это можно обобщить на любую команду, завершение которой можно предсказуемым образом наблюдать извне.

Очередь неупорядочена и может вызвать проблемы — если вы запустите

sudo apt update && sudo apt upgrade

и поставить установку в очередь во время работы apt update, вы можете закончить тем, что apt installзапускается после apt update, а apt upgradeзавершается ошибкой, потому что не может получить блокировку.

1
16.04.2021, 10:43
1 ответ

Предварительное примечание

Отображение «стеклянной панели прогресса или часа -, чтобы пользователи не думали, что она просто зависла», независимо от того, не зависает ли unzip, было бы довольно просто. В этом ответе я предполагаю, что вы не хотите вводить пользователей в заблуждение. Ответ пытается показать прогресс unzip, а не просто поддельный индикатор.


Самый простой метод

Если вашunzipможет читать со стандартного ввода и вы хотите извлечь весь архив, измерьте прогресс при чтении архива:

< /path/to/archive.zip pv | unzip -

pvможно заменить любым инструментом, который отображает информацию о ходе работы и передает данные.


Другие общие методы

Если ваш unzipне может читать со стандартного ввода, но вы уверены, что в архиве есть только один файл, и вы знаете имя, которое хотите использовать для извлеченного файла, извлеките его в стандартный вывод и передайте через pvв получить индикатор прогресса:

unzip -p /path/to/archive.zip | pv > /extracted/name

Если в архиве может быть больше файлов, то нужно указать один файл для извлечения:

unzip -p /path/to/archive.zip internal/path/to/compressed/file | pv > /extracted/name

При извлечении множества файлов с помощью одного unzip -pони будут объединены в /extracted/name. Чтобы извлечь более одного файла, запустите unzipмного раз, каждый раз перенаправляя на другой путь.

Если вы не знаете внутренних имён, то вам нужно заранее разобрать unzip -lили unzip -v. Таким образом вы также можете узнать несжатый размер, если хотите использовать его с pv -s. Признаюсь, я не знаю, насколько стабильны и разборчивы (однозначно )вообще эти форматы.

С помощью unzip -pвы не получите журнал от unzip. Положитесь на его статус выхода. Если вам нужен какой-то лог, то в него должен писать сам шелл-скрипт. Сценарий должен знать как минимум /extracted/name, чтобы он мог регистрировать как минимум это.


ПРЕДОХРАНИТЕЛЬ?

Я ожидаю, что любое решение на основе FUSE -позволит вам использовать любой инструмент, способный копировать обычный файл. Затем индикатор выполнения может зависеть от инструмента.Команда может быть такой простой, как:

pv /mountpoint/internal/path/to/compressed/file > /extracted/name

Это не обязательно вам поможет. Я проверил fuse-zip. Кажется, он извлекает (во временный файл или в память, что угодно ), прежде чем фактический инструмент копирования сможет начать свою работу. Таким образом, фактическое извлечение по-прежнему не имеет индикатора выполнения; выбранный инструмент может указывать только на копирование уже извлеченного файла позже. Кэширование «очень большого файла» имеет свои проблемы, я не уверен, пытается ли инструмент их решить и как. Не имеет значения, потому что fuse-zipвсе равно не может решить вашу первоначальную проблему.

Я также тестировал archivemount. Индикатор выполнения pvзапустился сразу же, но вся установка была мучительно медленной. Я обнаружил archivemountпрыжков (ищет )внутри архива туда и обратно, даже если процесс чтения читается последовательно. Вероятно, это будет нецелесообразно для вашего «очень огромного файла». Возможно какие-то правки возможны, может я их пропустил.


Трюк сpv

Умный, но несколько громоздкий метод заключается вpv -d:

unzip /path/to/archive.zip > output.log &
pv -d "$!"
wait "$!"

Этот метод должен подойти, чтобы «пользователи не думали, что он просто завис», хотя в своей базовой форме он покажет пользователям больше, чем вы, вероятно, хотите. Некоторые варианты pvили даже "ручной" разбор /proc/$!/fdи /proc/$!/fdinfoбез pvмогут помочь.

unzipпри работе в фоновом режиме будет сложно получить ответ от пользователя, поэтому относитесь кunzip -o(с осторожностью ).

pvзавершится после завершения unzip, поэтому нет необходимости в wait, если вы хотите строго ждать. wait "$!"предназначен для возврата статуса выхода из unzip.

0
28.04.2021, 22:52

Теги

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