Как скачать архив и извлечь его без сохранения архива на диск?

Вопрос или проблема

Я хотел бы скачать и распаковать архив в заданную директорию. Вот как я делал это до сих пор:

wget http://downloads.mysql.com/source/dbt2-0.37.50.3.tar.gz
tar zxf dbt2-0.37.50.3.tar.gz
mv dbt2-0.37.50.3 dbt2

Я хотел бы вместо этого скачать и распаковать архив на лету, без записи tar.gz на диск. Я думаю, что это возможно, перенаправив вывод wget в tar и указав tar целевой каталог, но на практике я не знаю, как правильно это сделать.

Вы можете сделать это, указав wget выводить свой результат в stdout (с флагом -O-) и подавив его собственный вывод (с флагом -q). Затем этот вывод становится входом (через stdin) для команды tar с помощью конвейера (|):

wget -qO- your_link_here | gunzip | tar xvf -

f - говорит tar, что архив следует читать из stdin. В некоторых tar реализациях это по умолчанию, в других это часто ленточное устройство.

Некоторые реализации tar могут самостоятельно обнаруживать сжатие и распаковывать архивы, в этом случае можно убрать | gunzip, некоторые поддерживают опцию z для распаковки архивов, сжатых gzip, на лету самостоятельно (часто вызывая gunzip).

Чтобы указать целевой каталог, если ваш tar поддерживает -C:

wget -qO- your_link_here | gunzip | tar xvf - -C /target/directory

Если нет:

(cd /target/directory && wget -qO- your_link_here | gunzip | tar xvf -)

Если у вас GNU tar, также можно переименовать выходную директорию:

wget -qO- your_link_here | tar --transform 's/^dbt2-0.37.50.3/dbt2/' -xvzf -

В tar от libarchive (bsdtar) или star, эквивалент с опцией -s/pattern/replacement/, как в стандартной команде pax.

Другой вариант – использовать curl, который по умолчанию пишет в stdout:

curl -s -L https://example.com/archive.tar.gz | tar xvz - -C /tmp

Эта однострочная команда делает то, что нужно:

tar xvzf -C /tmp/ < <(wget -q -O - http://foo.com/myfile.tar.gz)

Краткое объяснение: правая часть в скобках выполняется первой (-q указывает wget выполнять это тихо, -O - используется для записи вывода в stdout).

Затем мы создаем именованный конвейер, используя оператор подстановки процесса из Bash <( для создания именованного конвейера.
Таким образом, мы создаем временный дескриптор файла и затем направляем содержимое этого дескриптора в tar, используя оператор перенаправления файла <.

Решение с именованным конвейером и стандартным вводом, и действительно обратите внимание на флаги для -xvz в tar

tar -xvz -C /tmp/ -f <(wget -q -O - https://github.com/user/repo/release/download/v/v.tar.gz)

Однострочный вариант, который обрабатывает перенаправления и может распаковывать файлы tar.bz2. Используйте xz для распаковки файлов gzip.

curl -L https://downloads.getmonero.org/cli/linux64 | tar xj

Часть распаковки должна принимать ввод из STDOUT. Возможно, понадобится tar -xzvf - -C <output_dir>

Пример:


# это может не сработать
# может вывести ошибку 
# tar (child): -C: Не удается открыть: Нет такого файла или каталога
wget -qO - https://dlcdn.apache.org/spark/spark-3.3.0/spark-3.3.0-bin-hadoop3-scala2.13.tgz | tar -xzvf -C /opt/spark --strip-component 1


# это должно сработать. 
wget -qO - https://dlcdn.apache.org/spark/spark-3.3.0/spark-3.3.0-bin-hadoop3-scala2.13.tgz | tar -xzvf - -C /opt/spark --strip-component 1


Ответ или решение

Как скачать архив и извлечь его без сохранения на диск

Для IT специалистов, которым необходимо извлечь содержимое архива из интернета без предварительного сохранения на локальный диск, это возможно благодаря использованию комбинации команд в Unix-подобных системах, таких как wget и curl, в связке с tar. Ниже представлены детальные методы для выполнения данной задачи.

Использование wget и tar

В Unix-системах доступ к команде wget позволяет загружать файлы из сети. Для извлечения архива на ходу можно перенаправить его вывод на стандартный ввод tar, который будет распаковывать данные по мере их получения:

wget -qO- http://example.com/archive.tar.gz | tar xvz -C /target/directory
  • -q: параметр указывает wget работать в тихом режиме, убирая весь лишний вывод.
  • -O-: переназначает вывод wget на стандартный поток (stdout).
  • | tar xvz: распаковывает архив, принимая данные напрямую из потока.
  • -C /target/directory: установка целевой директории для извлечения.

Альтернатива с использованием curl

Команда curl также хорошо подходит для загрузки данных и уже по умолчанию выводит результат в stdout. Пример команды с curl:

curl -sL http://example.com/archive.tar.gz | tar xvz -C /target/directory
  • -s: тихий режим, убирает прогресс-бар.
  • -L: следование за редиректами.
  • Другие параметры tar аналогичны предыдущему примеру.

Использование именованных каналов в Bash

Командная оболочка Bash предоставляет механизм использования именованных каналов для передачи данных между процессами без промежуточного сохранения:

tar xvz -C /target/directory < <(wget -qO- http://example.com/archive.tar.gz)

Эта конструкция включает:

  • < <(...): синтаксис процесса замещения. Запускает команду в скобках и заменяет её вывод специальным временным файлом, который становится источником данных для tar.

Вывод

Использование вышеуказанных методов позволяет экономить дисковое пространство и время при работе с архивами, особенно в контексте CI/CD процессов или когда местное хранилище ограничено. Эти команды являются значимыми инструментами для разработчиков и системных администраторов, стремящихся к повышению эффективности рабочих процессов.

Если у вас возникнут дополнительные вопросы или потребуются специфические опции команды, пожалуйста, обращайтесь за консультацией, мы всегда рады помочь профессиональным советом IT-специалистам.

Оцените материал
Добавить комментарий

Капча загружается...