将标准输入传递给zip命令,如何指定文件名?

32

我想使用zip压缩标准输入(stdin)的内容,例如:

echo 'foo bar' | zip  > file.zip

这个方法可以正常工作,但是在解压时,未压缩的文件名是-

我想知道如何为标准输入指定一个文件名?


请参考 https://dev59.com/SHI-5IYBdhLWcg3wFkSO 中的相同问题。 - valentin
4
不完全相同,因为在那里,他们的工作是基于假设,在数据到来之前不知道文件名。也许Mehdi(这是我的用例)在编写Bash命令行时就知道他们想要将文件命名为什么。基本上,这是一个更有效率的版本:echo 'foo bar' > FILENAME && zip file.zip FILENAME && rm FILENAME - Hashbrown
4个回答

15

这并不理想,因为您无法在流设置中使用它(如果zip本身正在其他地方进行流传输)。 - polvoazul
我认为这是不可能的,zip没有提供强制命名的选项。如果您可以接受以某种方式创建“文件”,那么一种方法是将数据命令管道传输到命名管道中,然后将该命名管道添加到流式传输的 zip 中(这将压缩一个新文件并以该名称命名)。 - Hashbrown

9

使用FIFO(命名管道)代替直接传输标准输入!

mkfifo text.txt               # create fifo
echo 'foo bar' > text.txt &   # pipe data to fifo, in background
zip --fifo file.zip text.txt  # note the `--fifo` argument to zip
rm text.txt                   # cleanup

结果:

$ unzip -l file.zip
Archive:  file.zip
Length      Date    Time    Name
---------  ---------- -----   ----
8          2020-11-29 12:30   text.txt
---------                     -------
8                             1 file

注意,FIFO是一个命名管道。就像匿名管道一样,也就是著名的|,不会存储数据在硬盘上,数据会直接从写入者流向读取者。

问题:如何确保zip进程在追上数据时不停止读取并退出?这是否取决于交换空间并容易短缺?一旦zip进程读取了一部分数据,空间是否会被回收(我知道这是一厢情愿的想法..)? - gk_2000
它比你想的要好 :) @gk_2000管道只是将生成数据的任何进程连接到压缩进程。如果数据尚未可用,则管道将阻止zip进程进行读取,并阻止生成进程如果zip没有以足够快的速度读取数据。因为没有浪费空间,所以也不会回收空间。生成器直接将其数据发送到zip。当生成器退出时,它关闭管道,管道向zip发出信号表明“文件结束”。 - polvoazul
换句话说,一切都“只是工作”。 - polvoazul

1
将echo输出写入所需的文件名,然后使用-m标志在一步中压缩并删除原始文件。 echo 'foo bar' > filename.txt && zip -m filename.txt.zip filename.txt

但是你这里没有使用管道。你首先要存储到磁盘中。 - Daniel F

-8

echo 'foo bar' | zip -@ /path/to/zipfile.zip 可以在保持文件名完整性的同时完成它。


17
这并不回答问题。原帖想要压缩字符串 'foo bar',而这个指令会压缩一个名为 'foo bar' 的文件。 - Thayne
这个可以完成任务,+1 - Matías Cánepa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接