文件扩展名是否有任何用途(用于操作系统)?


73

Linux通过文件头中的代码确定文件的类型。它不依赖文件扩展名来知道要使用哪个软件来打开文件。

这就是我从教育中所记得的。如果我错了,请纠正我!

工作一点与Ubuntu系统最近我看到很多文件上有这样的扩展系统.sh.txt.o.c

现在我在想:这些扩展名仅适用于人类吗?这样一来,您便可以了解文件的类型是什么?

还是它们对操作系统也有用途?


5
如果您在这里没有得到很好的回应,请记住还有unix.stackexchange.com
mchid '16



5
在Windows他们这样做,在的Linux / Unix,他们大多不知道。主要的例外是压缩节目- ,,gzip -等。这些程序使用后缀将文件的压缩版本与它们替换的未压缩版本分开。压缩程序通常会抱怨后缀不正确,即使该文件实际上是应该处理的类型的压缩文件。bzip2xz
巴德·科珀罗德

6
我认为这个问题的部分问题在于“操作系统”不是一个定义明确的概念。什么是操作系统的一部分,以及在它之上的应用程序是什么?操作系统的任何部分(无论我们在谈论的是哪种操作系统)都没有在乎文件的类型-它们只是按照提示执行操作。因此,关于他们如何知道的区分是无关紧要的。他们都不做。另一方面,应用程序可能会做一件事或两件事。
IMSoP '16

Answers:


39

Linux通过文件头中的代码确定文件的类型。它不依赖于文件扩展名来知道用于打开文件的软件。

这就是我从教育中所记得的。如果我错了,请纠正我!

  • 正确记住。

这些扩展仅适用于人类吗?

  • 是的,但是。

当您与确实依赖扩展名的其他操作系统进行交互时,使用扩展名是更明智的主意。

在Windows中,扩展程序附带了打开软件。

打开名为“文件”是Windows比打开一个名为“file.txt的”同一个文件更难的文本文件(你将需要从切换打开文件对话框*.txt,以*.*每次)。TAB和分号分隔的文本文件也是如此。导入和导出电子邮件(扩展名为.mbox)也是如此。

特别是在编写软件时。与“ software.html”和“ software.js”相比,打开名为HTML的文件“ software1”和作为JavaScript文件的“ software2”变得更加困难。


如果Linux中有一个文件扩展名很重要的系统,那我就称之为bug。如果软件依赖文件扩展名,则可以利用。我们使用解释器指令来识别文件是什么(“文件中的前两个字节可以是字符“#!”,它构成了一个魔术数字(十六进制的23和21,ASCII值分别为“#”和“! “),通常称为shebang,”)。

文件扩展名最著名的问题是Windows上的LOVE-LETTER-FOR-YOU.TXT.vbs。这是一个视觉基本脚本,在文件资源管理器中显示为文本文件。

在Ubuntu中,当您从Nautilus启动文件时,您会得到一条警告,警告它将要做什么。从Nautilus执行脚本以启动要在其中打开gEdit的软件显然是一个问题,我们收到有关此警告。

在命令行中执行某些操作时,您可以直观地看到扩展名。如果它以.vbs结尾,我将开始变得可疑(不是.vbs在Linux上是可执行的。至少没有付出更多的努力;)。


31
我完全不明白你在最后一句话中想说的话。首先,这是隐藏扩展而不是拥有扩展的问题,其次,该漏洞利用程序在Linux中的工作原理相同-您命名一个二进制文件readme.txt并使之可执行。如果用户执行了它,它不会打开编辑器,而是运行代码。在这方面,使扩展很重要(但不隐藏扩展名)对于非精明用户来说更安全,也更容易解释。还有其他区别(最显着的是不执行当前目录中的文件),但是它们与扩展名无关。
techraf

4
@techraf实际上,文件管理器可能会尝试readme.txt使用文本编辑器打开文件。我刚刚在KDE中尝试了海豚,创建了一个添加可执行权限的shell脚本,将其另存为.txt并单击它将使其在Kate中打开。如果我将其重命名为,.sh则单击它即可运行它。
巴库里

9
linux:因为make是围绕依赖于文件扩展名的规则构建的,所以make(没有双关语)扩展名不仅对人类有意义吗?
bolov '16

15
这是一个错误的答案。Linux的某些部分使用幻数来确定文件类型。在命令行执行文件。但是系统的其他大部分使用文件扩展名来了解内容,无论这些文件是动态链接程序(需要.so文件),modprobe,构建系统,插件,用于python,ruby的库,还是许多文件。 t具有魔术数file,不是基于启发式的。
艾伦·舒特科

3
“ Linux通过文件头中的代码确定文件的类型”“正确” WTF?什么是“文件头中的代码”?没有这样的代码,在Linux中也没有这样的通用“文件头”。
leonbloy

68

这里没有100%黑色或白色的答案。

通常, Linux不依赖文件名(和文件扩展名,即通常在最后一个句点之后的文件名的一部分),而是通过检查其内容的前几个字节并将其与已知幻数的列表进行比较来确定文件类型。。

例如,所有位图图像文件(通常带有扩展名.bmp)必须BM在其前两个字节中以字母开头。大多数脚本语言(例如Bash,Python,Perl,AWK等)中的脚本(基本上,所有将行以#注释开头的东西都包含)可以像#!/bin/bash第一行一样包含shebang 。此特殊注释告诉系统使用哪个应用程序打开文件。

因此,通常情况下,操作系统依靠文件内容而不是文件名来确定文件类型,但是声明Linux上永远不需要文件扩展名只是事实的一半。


应用程序当然可以根据需要实现其文件检查,其中包括验证文件名和扩展名。一个示例是Gnome的Eye(eog标准图片查看器),它通过文件扩展名确定图像格式,如果内容不匹配,则会引发错误。可以讨论这是错误还是功能...

但是,甚至操作系统的某些部分都依赖于文件扩展名,例如,在解析软件源文件时/etc/apt/sources.list.d/-仅*.list解析具有扩展名的文件,其他所有文件均被忽略。它可能不是主要用于确定文件类型,而是用于启用/禁用某些文件的解析,但它仍然是文件扩展名,会影响系统处理文件的方式。

当然还有人类用户利润的文件扩展名是最使明显的一个文件的类型,也可以用相同的基本名称的多个文件,并喜欢不同的扩展site.htmlsite.phpsite.jssite.css等缺点当然是文件扩展名,实际文件类型/内容不一定必须匹配。

另外,跨平台的互操作性还需要它,例如Windows将不知道如何处理readme文件,而只知道一个readme.txt


您在这里略有矛盾:如果标准图像查看器要求文件名以.bmp结尾,那么您说操作系统的哪一部分依赖于以“ BM”开头的文件内容?据我所知,唯一的“幻数内核关心的是可执行的类型,包括的特殊情况下,#!其他的都是最高的一些应用程序的决定。
IMSOP

@IMSoP我不知道确切的实现,eog也不知道为什么他们根本不在乎文件名。我认为这是一个错误。当然,如果文件名为“ bmp”,但是其内容格式不匹配,那么当然也会出现错误。当然,每个应用程序都决定如何验证文件,但是通常,Linux应用程序不应依赖该名称。顺便说一句,您可以使用此file命令通过文件内容检查文件类型。
字节指挥官

1
我要挑战的一句话是:“ Linux ...通过检查前几个字节来确定文件类型”。您在该句子中使用的“ Linux”的定义是什么?该file实用程序的存在并不能证明什么。这是一个有用的工具,可以在任何操作系统上存在。操作系统的哪个基本部分使运行file比使文件名更“正确”?
IMSoP '16

请注意,没有扩展名的文件可以与程序关联。
isanae

24

就像其他人提到的那样,在Linux中使用解释器指令方法(将文件中的某些元数据存储为标头或幻数,以便可以告诉正确的解释器读取它),而不是Windows使用的文件名扩展名关联方法。

这意味着你可以创建一个文件几乎任何你喜欢的名字...... 有几个例外

然而

我想提一个警告。

如果系统上使用文件名关联的系统上有一些文件,则这些文件可能没有魔术数字或标头。文件扩展名被能够读取它们的应用程序用来标识这些文件,如果重命名这些文件,则可能会遇到一些意想不到的影响。例如:

如果您将文件重命名My Novel.docMy-Novel,Libreoffice仍然可以打开它,但是它将以“无标题”打开,并且您必须再次命名才能保存它(Libreoffice默认情况下会添加扩展名,因此您可以两个文件My-NovelMy-Novel.odt,可能会很烦人)

更严重的是,如果将文件My Spreadsheet.xlsx重命名为My-Spreadsheet,则尝试用它打开它xdg-open My-Spreadsheet会得到它(因为它实际上是压缩文件):

而且,如果您将文件重命名My Spreadsheet.xlsMy-Spreadsheet,则出现xdg-open My-Spreadsheet错误提示

错误打开位置:没有应用程序注册为处理此文件

(尽管在这两种情况下,只要您都可以正常运行soffice My-Spreadsheet

如果您随后将无扩展名文件重命名为My-Spreadsheet.odswith mv并尝试将其打开,则会得到以下信息:

(修复失败)

而且,您必须重新打开原始扩展名才能正确打开文件(然后,您可以根据需要转换格式)

TL; DR:

如果您有带有扩展名的非本地文件,请不要删除扩展名,除非一切正常!


4
没有文件扩展名的新型MS Office文档(docx,xl​​sx,pptx等)会在存档管理器中打开,因为这些文件类型实际上只是普通的ZIP压缩文件,其中包含定义文档内容所需的所有XML文档和媒体文件。如今,ZIP压缩目录的文件格式非常普遍。
字节指挥官

1
我已经注意到很多不错的答案,但还有一个针对libreoffice的答案。创建一个逗号分隔值(CSV)的文件并将其另存为“ test.csv”,将打开一个窗口,询问您使用的是哪种类型的分隔符(即libreoffice Calc)。例如,如果将此文件重命名为“ test.cs”,则libreoffice的Writer将其打开。因此,除了上面的ZIP示例,似乎libreoffice确实使用了文件扩展名。

3
linux文件系统对文件类型不做任何事情。这完全取决于在其之上运行的程序。
彼得·格林

@PeterGreen是的,但是程序确实为其赋予了重要性,这一事实意味着它并不“适合人类”,例如,经典的MacOS拥有[没有四个字节的“文件类型”和“创建者应用”字段”。文件名的一部分,因此操作系统和应用程序无需查看文件扩展名即可获得所需的所有信息]
Random832 '16

3
@PeterGreen Windows文件系统也不对文件类型做任何事情。图形外壳程序(Windows Explorer)使用文件扩展名来选择双击操作,但从技术上讲,就像Nautilus一样,它只是在OS之上运行的程序。完全有可能编写具有这种行为的Linux文件管理器,或者编写检查文件内容的Windows文件管理器。
IMSoP '16

20

我想采用与其他答案不同的方法,并挑战“ Linux”或“ Windows”与此有关的概念(由我来承担)。

文件扩展名的概念可以简单地表达为“根据文件名的一部分来识别文件类型的约定”。识别文件类型的其他常见约定是将其内容与已知签名的数据库进行比较(“幻数”方法),并将其作为额外属性存储在文件系统上(原始MacOS中使用的方法) 。

由于Windows或Linux系统上的每个文件都具有名称和内容,因此想要了解文件类型的进程可以根据需要使用“扩展名”或“幻数”方法。通常无法使用元数据方法,因为在大多数文件系统中,此属性没有标准位置。

在Windows上,使用文件扩展名作为识别文件的主要方法有着悠久的传统。最明显的是,当您双击文件确定要启动哪个应用程序时,图形文件浏览器(Windows 3.1上为“文件管理器”,现代Windows上为“资源管理器”)使用了它。在Linux(以及更普遍的基于Unix的系统)上,检查内容有更多的传统。最值得注意的是,内核会查看直接执行的文件的开头,以确定如何运行它。脚本文件可以通过以开头,#!后跟指向解释器的路径来指示要使用的解释器。

这些传统会影响为每个系统编写的程序的UI设计,但是有很多例外,因为每种方法在不同情况下都有优缺点。使用文件扩展名而不是检查内容的原因包括:

  • 与检查文件名相比,检查文件内容是相当昂贵的;因此,例如“查找所有名为* .conf的文件”将比“查找第一行与此签名的所有文件”要快得多。
  • 文件内容可能不明确;许多文件格式实际上只是以特殊方式处理的文本文件,许多其他文件是经过特殊构造的zip文件,为这些文件定义准确的签名可能很棘手
  • 一个文件实际上可以是多种类型的有效文件;HTML文件也可能是有效的XML,同时链接在一起的zip文件和GIF仍对两种格式均有效
  • 幻数匹配可能会导致误报;没有标题的文件格式可能会以“ GIF89a”字节开头,并且被误识别为GIF图片
  • 重命名文件是将其标记为“已禁用”的便捷方法;例如,将“ foo.conf”更改为“ foo.conf〜”以表明备份比编辑文件以注释掉其所有指令更容易,并且比将文件移出自动加载目录更方便;同样,将.php文件重命名为.txt会告诉Apache将其源代码作为纯文本提供,而不是将其传递给PHP引擎

默认情况下使用文件名的Linux程序示例(但可能具有其他模式):

  • gzip和gunzip对以“ .gz”结尾的任何文件进行特殊处理
  • gcc会将“ .c”文件作为C处理,并将“ .cc”或“ .C”作为C ++处理

Windows还具有隐藏扩展名的传统,如果扩展名“众所周知”,甚至DOS都允许命令忽略.COM,.BAT和.EXE,自动搜索这些扩展名以确定要执行的实际程序。* nix中没有这样的传统。
蒙迪·哈德

这是一个更好的答案,但是有一个事实错误...无法通过将脚本放在#!开头来使脚本可执行。设置了可执行位的任何文件都可以通过以下几种方式之一执行。#!/bin/bash和类似的签名仅指定要使用的解释器。如果没有提供这样的签名,则使用默认的shell解释器。仅包含两个单词“ Hello World”但设置了执行位的文件将在运行时尝试查找“ Hello”命令。
DocSalvager '16

1
@DocSalvager不错,这措辞很笨拙。我对它进行了重新措辞,以明确说明shebang不能使脚本可执行,它只是改变执行方式。
IMSoP '16

15

实际上,某些技术确实依赖文件扩展名,因此,如果在Ubuntu中使用这些技术,则也必须依赖扩展名。一些例子:

  • gcc使用扩展名来区分C和C ++文件。没有扩展名,就很难区分它们(想象一个没有类的C ++文件)。
  • 许多文件(docxjarapk)都只是特别结构的ZIP压缩文件。尽管通常可以从内容中推断出类型,但并非总是可能的(例如,Java Manifest 在文件中是可选jar)。

在这种情况下,不使用文件扩展名只能通过巧妙的解决方法来实现,并且很容易出错。


提起编程对您有好处,但是您弄错了大多数细节。 gcc是C文件的前端,对于C ++文件,您需要g++前端或命令行开关来指定语言。更重要的是,该make程序决定使用gcc还是g++构建特定文件-并make完全依赖于文件名模式(主要是扩展名)进行规则匹配。
Ben Voigt

@BenVoigt编译带有.cc扩展名的文件时gcc,它实际上将被编译为C ++,其记录man gcc如下:“对于任何给定的输入文件,文件名后缀确定要进行的编译类型:”,后跟列表。扩展及其处理方式。
播放

1
@hvd然后,如果您不使用正确的前端,那可能是默认的一组库会出错。无论如何,make是最好的例子,因为它所做的一切都是基于文件扩展名的。
Ben Voigt

1
@BenVoigt make也是一个很好的例子,但gcc同样严重依赖文件名。这是一个比.cvs 更清楚的示例.cc:对于C,gcc使用后缀来表明其第一步是预处理(.c),编译(.i),汇编(.s)还是链接(.o)。在这里,我使用-E-S-c告诉gcc在哪里停止,但它使用的文件名知道从哪里开始 gcc something.cc不会链接到正确的C ++库,但是会将文件视为C ++,这就是为什么许多用户会因出错而收到错误消息而感到困惑。
伊利亚·卡根

7

您的第一个假设是正确的:Linux上的扩展无关紧要,仅对人类(以及其他关心扩展的非类Unix操作系统)有用。文件的类型由文件中的前32位数据确定,这称为幻数。 这就是为什么Shell脚本需要#!换行-告诉操作系统要调用的解释器。没有它,shell脚本就是文本文件。

就文件管理器而言,他们确实想知道某些文件的扩展名,例如.desktopfiles,这些扩展名与Window的快捷方式版本基本相同,但功能更多。但是就操作系统而言,它需要知道文件中的内容,而不是名称中的内容


3
这不是真的。有些程序需要特定的扩展名。最常用的例子可能是gunzip如果不调用它不会解压缩文件foo.gz
terdon

那是特定软件的实现。在大多数情况下,类Unix系统上的实用程序不希望扩展。
Sergiy Kolodyazhnyy

7
在大多数情况下,它们不是。但是,您的第一句话声称它们从未使用过,而仅对人类重要。那不是完全正确的。gunzip是一个例子,eog是另一个。同样,如果没有正确的扩展名,许多工具也不会自动完成名称。我要说的是,它比“扩展始终无关紧要”要复杂得多。
terdon

1
1个小问题:OP询问了操作系统。'gunzip'和'eog'不是操作系统,而是决定创建自己的限制(在使用gunzip的情况下)或方法(eog)。虽然是“哑剧类型”。
林茨温德

1
@Serg当然,您可以狭义地定义操作系统,并获得关于该问题的简单答案。但是,这并不是一个特别有用的答案,因为用户使用计算机所做的绝大多数工作都与您所排除的软件有关。请注意,该问题将“仅适用于人类”与“操作系统”进行了对比。我认为它们的意思不是“内核”。
IMSoP '16

6

这对于评论答案来说太大了。

请记住,即使含义不同,即使“扩展名”也有很多含义。

您所谈论的似乎是结帐后的3个字母。DOS使得8.3格式非常流行,而Windows至今仍使用.3。

Linux有许多文件,例如.conf或.list或.d或.c,这些文件具有含义,但实际上并不是8.3扩展名。例如,Apache在/etc/apache2/sites-enabled/website.conf中查找其配置指令。尽管系统使用MIME类型和内容标头以及无法确定它是文本文件的内容,但是Apache(默认情况下)仍然不会在不以.conf结尾的情况下加载它。

.c是另一个很棒的例子。是的,这是一个文本文件,但是gcc取决于main.c成为main.o并最终成为main(在链接之后)。系统在任何时候都不会使用.c,.o或不使用扩展名来使内容具有任何含义,但会使用。后面的内容。确实有一些意义。您可能会设置SCM以忽略main.o和main。

重点是:扩展名没有像在Windows中那样被使用。内核将不执行.txt文件,因为您删除了名称的.txt部分。如果设置了执行权限,执行.txt文件也非常高兴。话虽如此,它们确实具有含义,并且仍然在“计算机级别”上用于许多事情。


1
窗户也没有绑定x.3的命名方案更多,你必须再扩展那里也一样.doxc.torrent.part等它只是多种文件格式和扩展已经被定义回来的时候8.3命名仍然是一个事,后来格式大多只是简单地采用了最多使用3个字母的约定。
字节指挥官

我看不到“ .conf”,“。c”等与“ 8.3感觉”有何不同。文件扩展名的概念可以简单地表达为“根据文件名的一部分来识别文件类型的约定”。甚至DOS / Win3.1都不需要正确的扩展名(您可以将Word文档称为“ STUPIDN.AME”,并在WinWord中使用Ctrl-O打开它)。只是某些系统(例如,双击Windows,gzip您的Makefile等)可能被编写为使用此约定对每个文件采取的正确操作做出假设。
IMSoP '16

@ByteCommander是的,但是扩展名仍然确定所使用的应用程序。我不确定如何编辑答案以反映这一点。
coteyr

1
@coteyr同样,这完全取决于我们所说的“操作系统”的含义。在文件管理器一定会抬头为“AME”注册表项,并会告诉我,“foo.txt的”是一个文本文件。但是dir在命令提示符下运行不会告诉我任何事情。它根本不在乎。在两个操作系统上,执行文件当然是一个例外。如果问题仅限于此,答案将是DOS / Windows 关心名称,而Unix / Linux 关心执行权限和文件的第一个字节。除此之外,总有一些应用程序选择遵循的约定。
IMSoP '16

1
@coteyr在Windows 3.1及更高版本中,您忘记了* .scr(屏幕保护程序二进制文件)。也就是说,即使在DOS / Windows系统中甚至对于可执行文件,文件扩展名仍然只是一个方便。具体细节在很大程度上取决于您在哪里划定“操作系统”的界限,但是您始终可以将二进制文件加载到内存中,然后自己跳入内存中,完成操作系统通常要求的工作。在MS-DOS中,如果您浏览command.com,我肯定会找到一个像EXE COM这样的列表,您可以对其进行编辑,以便在未指定扩展名的情况下查找其他扩展名(不是说这是个好主意,提个醒)。
CVn
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.