【问题标题】:dos2unix modifies binary files - whydos2unix 修改二进制文件 - 为什么
【发布时间】:2016-03-19 09:30:20
【问题描述】:

默认情况下它不应该影响二进制文件。

我在一个包含图像的文件夹中对其进行了测试,尽管大多数图像没有受到影响,但也有一些受到影响。如果dos2unix 无法区分二进制文件和文本文件,我是否必须专门包括和/或排除某些文件扩展名才能使其正常工作?

注意:当我在任何 jpg 上运行 file image.jpg 时,无论它是否被修改,结果是:

JPEG image data, JFIF standard 1.01

【问题讨论】:

  • 是什么让您认为它不应该“默认”影响二进制文件?它只是用 LF 替换 CR/LF 序列。
  • "cannot tell a binary file from a text file"没有区别,每个文件都是二进制的。
  • stackoverflow.com/a/19284034/631764 声称确实如此,但我想我应该查看手册页。
  • @timgeb 谢谢,这非常有用。不幸的是,我需要确保图像文件没有被更改,因为这会损坏它们,而更改 phpjsphtmltxt 文件中的换行符不会损坏这些文件。
  • 来自 centos6.6 上的man dos2unixBinary files are automatically skipped, unless conversion is forced.

标签: centos6 line-endings dos2unix


【解决方案1】:

这是dos2unix程序源码的相关部分:

if ((ipFlag->Force == 0) &&
      (TempChar < 32) &&
      (TempChar != 0x0a) &&  /* Not an LF */
      (TempChar != 0x0d) &&  /* Not a CR */
      (TempChar != 0x09) &&  /* Not a TAB */
      (TempChar != 0x0c)) {  /* Not a form feed */
        RetVal = -1; 
        ipFlag->status |= BINARY_FILE ;
        if (ipFlag->verbose) {
          if ((ipFlag->stdio_mode) && (!ipFlag->error)) ipFlag->error = 1;
          d2u_fprintf(stderr, "%s: ", progname);
          d2u_fprintf(stderr, _("Binary symbol 0x00%02X found at line %u\n"),TempChar, line_nr);
        }
        break;
      } 

似乎如果文件有其他控制字符,则将其视为二进制文件并被跳过,否则将其作为文本文件处理。因此,如果二进制文件(例如图像)不包含这些字符,它将被损坏。

【讨论】:

  • file 正确识别这些文件,而 dos2unix 没有。即使我更改了 php 文件的文件扩展名,file 仍然将它们识别为 php 文本文件。即使我重命名 php 文件以赋予其 jpg 扩展名,file 仍将其正确识别为 PHP script text
  • dos2unixfile 都不使用文件名作为确定文件类型的来源。代码 sn-p 显示了dos2unix 如何确定文件的类型。 file 程序更复杂,首先它尝试将操作系统知识用于特殊文件(例如设备文件),然后检查文件内容,详情参见man file。实际上你可以完全省略文件名,例如head /dev/zero | file -。对于您的任务,您可能需要明确指定文件名。
  • 我本可以使用findfiledos2unix 的组合来完成我的壮举,但我使用了更简单的file + dos2unix,仅限于某些文件扩展名如下:find -type f -regex ".*\.php\|.*\.js\|.*\.xml\|.*\.phtml\|.*\.css" -exec dos2unix "{}" \; 不过,您的回答非常直接地解决了我的问题。感谢您和 Matteo,我现在更了解这两个工具(filedos2unix)。
  • 我写了一个行尾转换实用程序来规避我对dos2unix的不满。除了检查文件是否包含非文本字符外,它还检查文件扩展名并避免使用您可能在源代码树中找到的 77 个最常见的扩展名修改文件。 jpg就是其中之一。你可以看看:github.com/mdolidon/endlines
【解决方案2】:

原则上没有“二进制”或“文本”文件之类的东西 - 所有文件都只是一个字节序列。

大多数尝试检测它们的程序只是使用某种启发式方法来排除包含文本中不常见的字符(通常是

这只是为了避免意外错误而对您的善意,但“不提供任何形式的保证”,因为完全有可能拥有仅使用 ASCII 字符的“二进制”文件(例如,PPM 很容易构建和通过上述测试的 COM 文件)。

【讨论】:

  • 仍然很奇怪filedos2unix 能更好地检测到差异。我想它会影响性能,但我宁愿再等几秒钟,这会破坏数千个“二进制”文件。
  • @ButtleButkus:一点也不奇怪,file 是完全不同的野兽;它有一个复杂的系统来检测特定文件类型(它实际上是libmagic的前端),匹配已知的文件类型签名,只有当这种类型的检测失败时,它才会退回到启发式(如果一切都失败了,它只会写入“数据”)。
  • 我很奇怪 dos2unix 没有应用类似的复杂系统。但我想这就是我们生活的世界。
  • @ButtleButkus:如果您需要使用file 机器,您应该在调用dos2unix 之前从脚本中调用它;无需复制功能。
  • 我想你是对的,Matteo。我选择只将dos2unix 应用于某些文件扩展名,这对我来说已经足够接近了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-25
  • 1970-01-01
  • 2014-11-28
  • 1970-01-01
  • 2011-05-27
  • 2018-03-27
相关资源
最近更新 更多