我想创建一个保留原始文件名的 gzip 文件。例如,压缩“example.txt”应该输出一个名为“example.txt”而不是“example.txt.gz”的压缩文件。是否可以使用一个命令优雅地执行此操作(而不是执行后续操作mv
)?
fro*_*utz 11
这不起作用:
# echo Hello World > example.txt
# gzip < example.txt > example.txt # WRONG!
# file example.txt
example.txt: gzip compressed data, from Unix, last modified: Thu Mar 21 19:45:29 2013
# gunzip < example.txt
<empty file>
Run Code Online (Sandbox Code Playgroud)
这是一个竞争条件:
# echo Hello World > example.txt
# dd if=example.txt | gzip | dd of=example.txt # still WRONG!
# gunzip < example.txt
Hello World # may also be empty
Run Code Online (Sandbox Code Playgroud)
问题在于> example.txt
(或dd of=example.txt
就此而言)在其他进程有机会读取文件之前杀死了该文件。所以没有明显的解决方案,这就是为什么你应该坚持使用mv
.
有很多方法可以作弊。您可以打开文件,然后取消链接 - 该文件将继续存在,直到您关闭它 - 然后创建一个具有相同名称的新文件并将 gzipped 数据写入该文件。但是我不知道强制 bash 使用它的明显方法,即使我知道,我的答案仍然是:
甚至不要这样做。
如果gzip
由于任何原因失败,或者出现任何问题,比如你在 gzip 压缩时空间不足(因为其他进程正在写入,或者 gzip 结果大于输入 - 这发生在随机数据 - 等等),你只是丢失了你的文件. 恭喜!
创建一个单独的文件并mv
成功。这是您能找到的最简单、易于理解和最可靠的方法。
tob*_*bek 10
作为 CI 部署到 AWS S3 的一部分,我遇到了同样的问题。
这是我为递归 gzip 没有.gz
后缀的目录(就地)所做的:
find . -type f -exec gzip "{}" \; -exec mv "{}.gz" "{}" \;
Run Code Online (Sandbox Code Playgroud)
对我来说似乎足够干净。但是是的,看起来你需要mv
在某个地方。
如果您正在使用,grunt
您可以查看grunt-contrib-compress
. 一些grunt
专门用于部署到 S3的工具也将为您处理 gzip。