Подтвердить что ты не робот

Как указать имена файлов в zip при создании в командной строке из канала?

Я пытаюсь создать zip файл из содержимого файла, на который подается канал, например.

mysql [params and query] | zip -q output.zip -

Это правильно пишет zip, но когда вы открываете zip, файл внутри него называется "-". Есть ли способ указать, что имя файла в каналах данных должно быть в zip файле?

4b9b3361

Ответ 1

Из того, что я могу собрать, вы не можете обойтись с командой zip, я имею в виду, что вы не можете указывать имена файлов и передавать контент. Вы можете либо передать содержимое, и результирующий файл -, либо вы можете передать имена файлов с помощью [email protected].

Это не значит, что делать это невозможно с помощью других методов. Я излагаю один из приведенных ниже. Это означает, что у вас должен быть установлен PHP и добавлен zip-расширение.

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

Это рабочий пример с использованием PHP

echo contents | php -r '$z = new ZipArchive();$z->open($argv[1],ZipArchive::CREATE);$z->addFromString($argv[2],file_get_contents("php://stdin"));$z->close();' test.zip testfile

Для запуска на окнах просто свопите одиночные и двойные кавычки. Или просто поместите script в файл.

"test.zip" - это полученный Zip файл, "testfile" - это имя содержимого, которое передается в команду.

Результат от unzip -l test.zip

Archive:  test.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
        6  01-07-2010 12:56   testfile
---------                     -------
        6                     1 file

И вот рабочий пример с использованием python

echo contents | python -c "import sys
import zipfile
z = zipfile.ZipFile(sys.argv[1],'w')
z.writestr(sys.argv[2],sys.stdin.read())
z.close()
" test5.zip testfile2

Результат unzip -l

Archive:  test5.zip
  Length     Date   Time    Name
 --------    ----   ----    ----
        9  01-07-10 13:43   testfile2
 --------                   -------
        9                   1 file

Результат unzip -p

contents

Ответ 2

Вы можете сделать это.

ls | zip test.zip [email protected]

это делается из понятия, что у меня есть 3 файла в каталоге.

-rw-rw-r-- 1 xxx domain users   6 Jan  7 11:41 test1.txt
-rw-rw-r-- 1 xxx domain users   6 Jan  7 11:41 test2.txt
-rw-rw-r-- 1 xxx domain users   6 Jan  7 11:41 test3.txt

и самого файла, результатом будет

Archive:  test.zip
  Length     Date   Time    Name
 --------    ----   ----    ----
        6  01-07-10 11:41   test1.txt
        6  01-07-10 11:41   test2.txt
        6  01-07-10 11:41   test3.txt
 --------                   -------
       18                   3 files

На странице Linux Zip Man

Если список файлов указан как - @, zip принимает список входных файлов от стандартного ввода.

Ответ 3

Вы можете использовать именованный канал и отправить на него вывод запроса, при этом записясь с него.

mkfifo output.txt ; mysql [params and query] > output.txt & zip output.zip -FI output.txt ; rm output.txt

Ответ 4

Мне не удалось справиться с ответом PHP (из памяти на больших дампах mysql), и FIFO не работал так, как я хотел, поэтому мое решение переименовать файл внутри ZIP-архива после запуска дампа, используя zipnote (который включен в пакет zip на Debian).

mysql [params and query] | zip -q output.zip -
echo -e "@ -\[email protected]=newname.sql" | zipnote -w output.zip

Ответ 5

mysql [params and query] | python3 -c "import sys as s,os,zipfile as m;z=m.ZipFile(os.fdopen(s.stdout.fileno(),'wb'),'w');z.writestr(s.argv[1],s.stdin.read());z.close()" 'filename.sql' > output.zip

В Python 3.5 добавлена поддержка записи в невидимые потоки.

Это не красиво, но работает.

Ответ 6

Ты можешь попробовать:

mysql [params and query] | zip -q output.zip [email protected]