Unzip/gunzip 在终端上运行良好,但从另一个 shell 调用时会出现错误

Unzip/gunzip 在终端上运行良好,但从另一个 shell 调用时会出现错误

我正在尝试从终端解压缩/gunzip 一个文件,并且它运行正常。

当我将其放入 sh 文件中并从终端调用它时,它也能正常工作!

 echo "started"
for file in $filepath/*; do
echo "filename ",$file
if [[ $file == *.zip ]]; then
        #unzip -o $path$file -d $path
      unzip $file
      #jar xvf $path$file -d $path
      #tar -xvf {$path$file} -C $path
      #rm $file
elif [[ $file == *.gz ]]; then
        #unzip -o $path$file -d $path
      gunzip $file
      #jar xvf $path$file -d $path
      #tar -xvf {$path$file} -C $path
  else
        echo "file name is not csv or zip ", $file
fi
done

但是当我从另一个 shell 脚本(它是 inotifywait 的一部分)调用它时,它会出现以下错误。对于 gz

gzip: /usr/apps/{somepath}/6206553653146575.csv.gz: unexpected end of file

用于 zip

Archive:  /usr/apps/{somepath}/3020393677273733265.csv.zip
End-of-central-directory signature not found.  Either this file is not
a zipfile, or it constitutes one disk of a multi-part archive.  In the
latter case the central directory and zipfile comment will be found on
the last disk(s) of this archive.
unzip:  cannot find zipfile directory in one of 
/usr/apps/{somepath}/3020393677273733265.csv.zip or
/usr/apps/{somepath}/3020393677273733265.csv.zip.zip, and cannot find 
/usr/apps/{somepath}/3020393677273733265.csv.zip.ZIP, period.

我已经尝试过什么:

将执行更改为 #!/bin/bash

尝试在文件名末尾添加 .zip/.gz。

谢谢你的帮助。非常感谢。

答案1

你提到inotifywait。我猜测您正在尝试在文件出现时立即提取它们。在某些情况下,它看起来unzipgunzip在它被告知提取的文件尚未完成时运行的。

可能的原因:

  • 您捕获了错误的事件(例如opencreatemodify),而不是那些表明文件现已完成的事件(moved_toclose_write)。
  • 您的脚本不会获取有关触发它的文件的信息。脚本使用for并尝试提取全部具有合适名称的文件。即使你在文件完成时正确捕获它,脚本也会尝试提取其他文件(如果有),包括不完整的文件。

需要改进的地方:

  • 捕捉正确的事件。
  • 重建逻辑,以便脚本知道它应该处理哪个文件。让每个文件触发自己的脚本实例,这样脚本的任何单个实例都只处理一个文件。它可能做得很少(例如,它可能会退出,因为文件的名称不是你想要的),但不要让它做太多(处理其他文件)。
  • 实现一些方法来确认给定的文件是完整的。一些想法:
    • 检查文件是否不再打开(fuserlsof);
    • 检查文件是否在几秒钟内没有增大;
    • 静默测试文件完整性(gunzip -tunzip -t)。

答案2

Termcap 正在搞乱你。我很少遇到它,我从来没有费心去了解确切原因,我只是绕过它。使用 strace 和 unzip,然后查看转储。

$ ls 
lorem_ipsum_2.zip  lorem_ipsum.zip
$ for z in lorem_ipsum.zip; do strace unzip $z 2>strace.dump; done

转到 stat 调用,就在文件打开之前,您将看到 termcap 颜色作为文件名的一部分(因此,您不会在控制台上看到它)。

stat("\[\033\[01;31lorem_ipsum.zip\[\033\[01;31", {st_mode=S_IFREG|0644, st_size=1544, ...}) = 0

如果您只是想解决这个问题,请执行如下操作。

$ LS_BU=$LS_COLORS;LS_COLORS=""
$ for z in $(ls *zip); do unzip $z; done
Archive:  lorem_ipsum_2.zip
  inflating: lorem_ipsum_2.txt
Archive:  lorem_ipsum.zip
  inflating: lorem_ipsum.txt
$ LS_COLORS=$LS_BU

如果你想解决这个问题,答案可能就在这里 https://www.gnu.org/software/termutils/manual/termcap-1.3/html_mono/termcap.html

答案3

解决了 ....

我正在使用 inotifywait,

避免错误的技巧是在 bucle 中添加 sleep 5,如下所示:

/usr/bin/inotifywait -m /你的文件夹 -e create | while read file; do sleep 5 对 $file 进行一些操作

相关内容