Вопрос или проблема
Я хотел бы скачать и распаковать архив в заданную директорию. Вот как я делал это до сих пор:
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-специалистам.