zip命令无法工作

15

我正在尝试使用Shell脚本命令压缩文件。我正在使用以下命令:

  zip ./test/step1.zip $FILES

$FILES包含所有的输入文件。但是我收到了以下警告:

    zip warning: name not matched: myfile.dat

还有一件事情是我观察到文件夹中最后一个文件在文件列表中,并且出现了上述警告,但是这个文件没有被压缩。

有人能解释一下这是为什么吗?我是shell脚本的新手。


4
你能提供 myfile.dat 文件的 ls -ltr 吗?我听说过一些文件太大或是符号链接的问题。 - eebbesen
8个回答

11

zip 警告:名称不匹配:myfile.dat

这意味着文件myfile.dat不存在。

如果该文件是指向不存在的文件的符号链接,您将会得到相同的错误信息。

正如您所说,无论在$FILES的末尾是什么文件,它都不会被添加到zip中并显示警告。因此我认为您创建$FILES的方式存在问题。很可能最后一个文件名末尾有换行符、回车符、空格、制表符或其他看不见的字符,导致了一个不存在的文件。例如,您可以尝试以下操作:

for f in $FILES; do echo :$f:; done

我敢打赌最后一行将是不正确的,例如:

:myfile.dat :

...或者类似这样的东西,而不是:myfile.dat:在最后一个:之前没有任何字符。

更新

如果你说运行了dos2unix脚本之后它开始工作了,那就证实了大家已经怀疑的事情,即$FILES列表末尾有回车符。

od -c 显示 \r 回车符。尝试 echo $FILES | od -c


但是我能够在给定的文件夹中看到那个文件。 - Aparna Savant
就像我说的,列表中最后一个文件出现了错误。如果我尝试将type.txt文件与$FILES文件一起压缩,那么type.txt会出现警告,并且不会被包含在压缩文件中! - Aparna Savant
3
那么我们需要更多的细节信息。$FILES中包含什么?按照要求展示一个ls。以下步骤对我有效:$ mkdir ziptest $ cd ziptest $ touch a b c $ mkdir d $ touch d/e $ zip foo.zip a b c d/e adding: a (stored 0%) adding: b (stored 0%) adding: c (stored 0%) adding: d/e (stored 0%) - Sean Perry
2
你如何创建 $FILES - janos
2
我敢打赌,在你的$FILES列表末尾有一个回车符。 - Donovan

5
另一个可能导致“zip警告:名称不匹配:”错误的原因是 zip 的任何环境变量设置不正确。

从man页面获取:

ENVIRONMENT
    The following environment variables are read and used by zip as described.

ZIPOPT
    contains default options that will be used when running zip.  The contents of this environment variable will get added to the command line just after the zip command.

ZIP
    [Not on RISC OS and VMS] see ZIPOPT

Zip$Options
    [RISC OS] see ZIPOPT

Zip$Exts
    [RISC OS] contains extensions separated by a : that will cause native filenames with one of the specified extensions to be added to the zip file with basename and extension swapped.

ZIP_OPTS
    [VMS] see ZIPOPT

在我的情况下,我在一个脚本中使用了zip,并将二进制文件的位置存储在环境变量ZIP中,这样我们就可以轻松更改到不同的zip二进制文件,而不必对脚本进行大量修改。
例子:
ZIP=/usr/bin/zip
...
${ZIP} -r folder.zip folder

这随后会被处理为:

/usr/bin/zip /usr/bin/zip -r folder.zip folder

并生成以下错误:

zip warning: name not matched: folder.zip
zip I/O error: Operation not permitted
zip error: Could not create output file (/usr/bin/zip.zip)

由于现在的压缩文件尝试将folder.zip添加到档案中,而不是将其用作档案,这就是第一个原因。第二和第三个原因是由于它试图使用文件/usr/bin/zip.zip作为档案,这是(幸运地)普通用户无法编写的文件。
注意:这是一个非常老的问题,但我没有在任何地方找到这个答案,所以我发布它来帮助未来的搜索者(包括我自己)。

1
我使用dos2unix命令将我的脚本转换为Unix环境,并通过执行./myscript.sh来运行脚本,而不是使用bash myscript.sh。

./myscript.shbash myscript.sh 都应该可以工作。如果你说在运行 dos2unix 后脚本开始工作了,那就证实了大家已经怀疑的事情,即 $FILES 列表末尾可能存在回车符。 - janos
@janos 没错,确实有一个回车符。但是如果我使用“bash myscript.sh”运行脚本仍然存在问题。但是使用“./myscript.sh”时,我的脚本可以完美运行! - Aparna Savant

1

eebbesen在他的评论中对我的情况点到了关键(但我无法为评论投票)。另一个可能被其他评论忽略的原因是文件超过了文件大小限制(4GB)。


0
虽然标题很广泛,但我在尝试压缩由docker-compose.yml创建的项目时遇到了类似的“警告”问题,其中mysql的数据保存在项目文件夹内的文件夹中。
当我尝试压缩时,出现了相同的错误,但是压缩文件可以创建一个包含除mysql.sock之外的所有文件的存档。尽管该文件存在,但zip无法压缩它。这是因为该文件正在被mysql使用,并且不断被读取/写入,而且它受到保护。
因此,无论何时您尝试压缩此类文件,都会收到该“警告”。因此,如果您不需要它们,请尝试查找此类文件并将其排除在外。
在我的情况下,我使用了“zip -rq .... -x '**/mysql.sock'”命令,它起作用了。

enter image description here


0
我也遇到了这个问题。在我的zip shell脚本中,行分隔符是CRLF,导致了这个问题。使用LF修复了它。

0

我刚刚发现了另一个可能导致这个问题的原因。如果目录/子目录的权限不允许zip找到文件,它将报告此错误。实际上,如果您在目录上运行chmod -R 444,然后尝试压缩它,您将重现此错误,并且还会有“stored 0%”的报告,如下所示:

zip warning: name not matched: borrar/enviar adding: borrar/ (stored 0%)

因此,请尝试更改文件的权限。如果您正在尝试通过电子邮件发送它们,并且那些电子邮件过滤器(例如Gmail的)发明了不发送可执行文件的愚蠢过滤器,请不要忘记在进行zip压缩时使权限非常严格可能是您报告的“名称不匹配”错误的原因。


0

不允许使用空格:

如果$FILES中有多个文件,除非将它们放入循环中,否则会失败。


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