Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
linux中的zip非确定性结果_Linux_Bash_Shell_Zip - Fatal编程技术网

linux中的zip非确定性结果

linux中的zip非确定性结果,linux,bash,shell,zip,Linux,Bash,Shell,Zip,我有这个剧本: #/bin/bash mkdir-pab echo hello>hello.txt echo world>world.txt zip-r-X-*.txt>a/helloworld.zip 睡眠3 触摸hello.txt zip-r-X-*.txt>b/helloworld.zip cat a/helloworld.zip | md5sum-czip文件格式包含此字段(请参阅) 这意味着,如果时间戳可能不同,那么对完整zip文件进行校验和的方法将永远不起作用 一种可能的方法是使用已

我有这个剧本:

#/bin/bash
mkdir-pab
echo hello>hello.txt
echo world>world.txt
zip-r-X-*.txt>a/helloworld.zip
睡眠3
触摸hello.txt
zip-r-X-*.txt>b/helloworld.zip

cat a/helloworld.zip | md5sum-czip文件格式包含此字段(请参阅)

这意味着,如果时间戳可能不同,那么对完整zip文件进行校验和的方法将永远不起作用

一种可能的方法是使用已经存储在zip存档中的CRC来进行每一个操作 档案中的文件。此字段是未压缩内容的CRC

您可以使用解压的
-lv
选项来获取CRC和文件名

$ unzip -lv z.zip
Archive:  z.zip
 Length   Method    Size  Cmpr    Date    Time   CRC-32   Name
--------  ------  ------- ---- ---------- ----- --------  ----
     175  Defl:N      127  27% 2020-06-21 22:34 2268840f  xxx
--------          -------  ---                            -------
     175              127  27%                            1 file
您可以对该输出运行
md5sum
,但首先删除时间戳数据,如下所示

$ unzip -lv z.zip | grep '^ *[0-9]' | sed -e 's/% [0-9-]* [0-9:]*/ /'
     175  Defl:N      127  27  2268840f  xxx
     175              127  27                           1 file
以下是基于您的脚本的概念证明

mkdir -p a b
echo hello > hello.txt
echo world > world.txt

zip -r -X - *.txt > a/helloworld.zip
sleep 3
touch hello.txt
zip -r -X - *.txt > b/helloworld.zip

unzip -lv a/helloworld.zip | grep '^ *[0-9]' | sed -e 's/% [0-9-]* [0-9:]*/ /'| md5sum
unzip -lv b/helloworld.zip | grep '^ *[0-9]' | sed -e 's/% [0-9-]* [0-9:]*/ /'| md5sum
这就产生了这个输出

$ sh /tmp/test.sh
  adding: hello.txt (stored 0%)
  adding: world.txt (stored 0%)
  adding: hello.txt (stored 0%)
  adding: world.txt (stored 0%)
be1ee35bf864a4a9f2394cc26d2c3b32  -
be1ee35bf864a4a9f2394cc26d2c3b32  -

正如其他地方提到的,zip文件包含时间戳,不能忽略它们。但是,可以将它们全部强制为单个值,这在生成可复制构建时非常有用

通常,这是通过
-o
-X
标志完成的
-o
将所有时间戳设置为存档中任何文件使用的最早时间,
-X
防止保存额外的每个操作系统时间戳

如果您知道只创建比最旧的文件更新的文件,则不需要执行任何其他操作。否则,您需要触摸给定的文件以生成适当的时间戳。您使用的时间戳并不重要,只要是一致的。例如,如果您的文件存储在Git中,您可能希望使用最新提交的提交者时间戳,或者您可能更喜欢使用历元;没关系

这看起来是这样的:

#!/bin/bash

archive () {
    local archive="$1"
    shift
    # Any suitable timestamp can be used here.
    touch -d 1970-01-01T00:00:00Z "$@"
    TZ=UTC zip -r -oX - "$@" > "$archive"
}

mkdir -p a b
echo hello > hello.txt
echo world > world.txt

archive a/helloworld.zip *.txt
sleep 3
touch hello.txt
archive b/helloworld.zip *.txt

cat a/helloworld.zip | sha256sum -c <( cat b/helloworld.zip | sha256sum -b )
#/bin/bash
存档(){
本地存档=“$1”
转移
#这里可以使用任何合适的时间戳。
触摸屏-d 1970-01-01T00:00:00Z“$@”
TZ=UTC zip-r-oX-“$@”>“$archive”
}
mkdir-pab
echo hello>hello.txt
echo world>world.txt
存档a/helloworld.zip*.txt
睡眠3
触摸hello.txt
存档b/helloworld.zip*.txt

cat a/helloworld.zip | sha256sum-c一个选项可以是用
unzip-p
替换
cat
。相关:@kaylum我尝试了你的建议,效果很好,即使它没有考虑文件名。我仍然不知道这是否是我的问题。@Socowi我需要使用linux提供的工具。对于我的用例,编写和使用python脚本是不可行的,如果您还需要文件名,那么就使用
-c
而不是
-p
$ sh /tmp/test.sh
  adding: hello.txt (stored 0%)
  adding: world.txt (stored 0%)
  adding: hello.txt (stored 0%)
  adding: world.txt (stored 0%)
be1ee35bf864a4a9f2394cc26d2c3b32  -
be1ee35bf864a4a9f2394cc26d2c3b32  -
#!/bin/bash

archive () {
    local archive="$1"
    shift
    # Any suitable timestamp can be used here.
    touch -d 1970-01-01T00:00:00Z "$@"
    TZ=UTC zip -r -oX - "$@" > "$archive"
}

mkdir -p a b
echo hello > hello.txt
echo world > world.txt

archive a/helloworld.zip *.txt
sleep 3
touch hello.txt
archive b/helloworld.zip *.txt

cat a/helloworld.zip | sha256sum -c <( cat b/helloworld.zip | sha256sum -b )