为什么将 .sh 文件复制到另一个文件夹时,其 md5sum 会发生变化?

为什么将 .sh 文件复制到另一个文件夹时,其 md5sum 会发生变化?

我从网页上下载了一个 sh 文件。我想将其复制到另一台机器,以便可以在那里安装它。另一台机器是 imx6 tiny rex。我尝试将我的 Ubuntu 机器复制/移动/scp 到另一台机器,似乎没问题,但是当我尝试执行它时,它会进行 md5 比较,告知 md5 已更改并停止该过程。

我尝试移动到 Ubuntu 机器内的另一个文件夹,但得到了相同的结果。

有没有办法复制(或移动,我不介意)并保持相同的 md5?将其 tar 起来是个好主意吗?

答案1

MD5被广泛用作快速查看文件是否被无意修改的方法。相同的数据始终具有相同的 MD5 哈希值,因此如果您传输文件,而目标位置的 MD5 哈希值与源位置的 MD5 哈希值不同,则该文件已损坏。

本答案介绍了此类问题的各种常见原因和解决方案。但如果你想尝试一些立即地,那么是的:你存档文件的想法tar可能会有效。(详情见下文。)

首先检查文件是否正确下载。

首先,最好先检查文件是否正确下载。下载文件的网站可能包含如何执行此操作的说明。如果这是一个调用md5sum或者类似的实用程序来计算其自己的 MD5 哈希值,并且您可以在下载它的机器上运行该脚本,这是测试它的一种方法。

如果没有关于您如何下载文件的具体信息,很难知道最可能导致损坏的原因。由于安装程序以包含二进制数据的 shell 脚本的形式提供,因此有时 Web 服务器会告诉您的浏览器一个不正确的MIME 类型针对文件。我自己也曾多次遇到过这个问题,.sh从软件供应商网站下载的文件就是如此。但我没有具体的理由认为这就是你的情况。

当你在两台机器之间传输文件时,可能会发生类似的问题。如果是这样,这个问题是一个你可以轻松解决的问题。

确保以正确的方式在机器之间传输文件。

其次,你应该检查如何您正在将文件从一台计算机传输到另一台计算机。一些以 shell 脚本形式提供的安装程序包含二进制数据这里的文件以及一些用于传输文件的协议——例如FTP-- 有单独的模式文本文件二进制文件。如果文件包含二进制数据,而该数据在传输过程中被错误地解释为文本,则目标文件可能会损坏。

如果您使用的是旧式 FTP 客户端,必须手动设置以文本还是二进制形式传输文件,则请在文件可能包含二进制数据时使用二进制模式,包括在这种情况下。

  • 为了确保你以二进制文件形式发送它ftp或类似的实用程序,您可以发出命令binary(在ftp>连接并准备传输文件后在提示符下),您应该被告知200 Type set to I,然后您可以put立即发出命令来发送文件。

许多现代 FTP 客户端通过查看文件的名称来自动确定是将文件作为文本还是二进制数据传输。.txt例如,带有扩展名的文件(例如 )可以作为文本发送。如果脚本的命名方式表明它是脚本(例如,如果它以 结尾.sh,正如您似乎表明的那样),那么此类 FTP 客户端可能会认为它仅由文本组成,就像大多数 shell 脚本一样。

  • 如果你的 ftp 客户端(或者可能是其他类型的程序,取决于你发送文件的方式)要检查文件本身的内部,而不仅仅是文件的名称,那么它可能会仍然犯这个错误,因为.sh带有二进制文档的文件通常以大量格式良好的文本开头。

有几种方法可以解决该特定问题。我建议使用以下三种解决方案之一。如果您使用的协议不是 FTP,但根据文件类型有不同的文件传输方式,这些方法也应该适用。

  • 告诉程序将文件以二进制形式传输。例如,你可以暂时让它传输全部文件作为二进制文件,或者您可以编辑文件扩展名的白名单(.sh)或 globs(*.sh)以删除导致其将该特定文件视为纯文本的条目。

  • 存档或压缩文件,以使其明确地成为二进制数据。正如您所建议的,使用tar它是实现此目的的一种方法。请注意,如果您使用的 FTP 客户端需要手动输入命令,并且默认为文本模式(这是交互式命令行 FTP 客户端的长期传统行为),那么这可能无济于事。但对于当今人们使用的大多数 FTP 客户端来说,它应该会有所帮助。

  • 使用不同的协议。具体来说,使用不会对不同类型的文件区别对待的协议。例如,如果你可以使用sftp或者scp,不受此问题的影响 - 它始终将文件视为二进制数据,并且检查以确保它们也被正确发送(尽管由于截断,目标位置仍可能损坏文件)。

    许多图形 FTP 客户端也支持 SFTP,但您必须告诉他们您想要这样做,这通常是通过在菜单中选择 SFTP 或在目标主机名前加上前缀来实现的sftp://

压缩或归档文件以便传输

正如您所建议的,您可以使用tar. 放入script.sh档案tar

tar cf script.sh.tar script.sh

然后,到达目的地:

tar xf script.sh.tar

或者,你可以用gzip

gzip -k script.sh

如果没有-kgzip则替换script.sh为压缩文件script.sh.gz。因此,如果您原始文件在源头被删除,那么您可以简单地省略-k并运行(或者之后删除该文件)。gzip script.sh

然后,到达目的地:

gunzip script.sh.gz

还有其他压缩方法,例如bzip2xz,但由于文件压缩得如何(甚至是否压缩)并不重要,因此您可以坚持使用gzip(或使用tar,如上所述)。

甚至可能只需重命名文件即可。

当然,如果问题是你的 FTP 客户端(或用于传输文件的其他程序)错误地推断该文件是纯文本,因为它的后缀名为.sh,那么改名文件。

但是,如果使用任何其他机制来检测文件的类型,那么这种方法就会失效——此外,如果文件的名称可能误导你,那么你可能会感到困惑。因此,我认为只重命名文件的方法很脆弱,我建议你改用上述方法之一。(它们并不比重命名更难——每种方法只需要在源处输入一个命令,在目标处输入另一个命令来撤消它。)

相关内容