在Linux中,文件扩展名有什么作用吗?

Linux通过文件头中的代码来确定文件的类型。这个过程不依赖于文件扩展名来知道使用哪个软件打开文件。
(这是我从教育中记得的,请在我错了的情况下纠正我!)
最近在使用Ubuntu系统时,我发现系统上有很多文件的扩展名是.sh、.txt、.o、.c等。
现在我想知道:这些扩展名的目的仅仅是帮助人们理解他们正在查看的文件的类型吗?还是它们对操作系统也有一些用途?

5如果你在这里得不到一个好的回应,记住还有http://unix.stackexchange.com。 - mchid
1相关的,几乎是重复的:http://askubuntu.com/questions/390015/why-do-i-have-to-name-my-text-file-something-cpp-in-order-to-compile-a-c-pro?rq=1 - AlwaysTalkingAboutMyDog
1相关: http://unix.stackexchange.com/questions/207276/how-are-file-types-known-if-not-from-file-suffix/207290#207290 - chaos
6在Windows中,它们会这样做,在Linux/Unix中,它们大多数情况下不会。主要的例外是压缩程序-gzipbzip2xz等等。这些程序使用后缀来区分文件的压缩版本和替换的未压缩版本。尽管文件实际上是应该处理的压缩文件类型,但压缩程序经常会抱怨后缀不正确。 - Baard Kopperud
6我认为这个问题的一部分问题在于“操作系统”并不是一个明确定义的概念。什么是操作系统的一部分,什么是它上面的应用程序?操作系统的很多部分(无论是哪个操作系统)都不关心文件的类型-它们只是按照指示执行任务。所以关于它们如何知道的区别是无关紧要的;它们既不做这些事情也不关心这些事情。另一方面,应用程序可能会做其中一种或两种事情。 - IMSoP
答案已经很好地涵盖了这一点,但我想补充一下,有些应用程序使用文件扩展名。 - Liam
文本编辑器用于语法高亮显示 - Liam
我所知道的最早使用文件扩展名的例子是由C编译器实现的;非常古老的C编译器工作方式是通过foo.c(源代码)-> foo.s(汇编器)-> foo.o(单独编译的输出)-> foo(链接输出)。在这种情况下,文件扩展名是必要的,以便不同的格式有不同的名称,满足内核级别的要求,即给定的文件名只与一个字节流相关联。 - Jonathan Cast
@jcast,它是/曾经是foo.c编译成foo.a,然后将foo.a汇编成foo。但从技术上讲,一切皆有可能,取决于“makefile”。 - DocSalvager
7个回答

这里没有百分之百的黑与白的答案。

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

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

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


应用程序当然可以按照自己的方式实现文件检查,包括验证文件名和扩展名。例如,Gnome 图像浏览器(eog)通过文件扩展名确定图像格式,并在不匹配内容时抛出错误。这是一个 bug 还是一个功能可以进行讨论...
然而,即使操作系统的某些部分也依赖于文件名扩展名,例如在解析软件源文件(/etc/apt/sources.list.d/)时,只有具有 *.list 扩展名的文件才会被解析,其他所有文件都会被忽略。这可能主要用于启用/禁用某些文件的解析,而不是确定文件类型,但它仍然是一个影响系统如何处理文件的文件扩展名。
当然,人类用户最受益于文件扩展名,因为它使文件类型明显,并且允许同一基本名称但不同扩展名的多个文件存在,例如 site.html、site.php、site.js、site.css 等。缺点当然是文件扩展名和实际文件类型/内容不一定匹配。
此外,这也是为了实现跨平台互操作性所必需的。例如,Windows系统不知道如何处理一个readme文件,但它可以处理readme.txt文件。

你在这里稍微自相矛盾了:如果标准图像查看器需要以 .bmp 结尾的文件名,那么你所说的操作系统的哪个部分依赖于文件内容以 "BM" 开头?据我所知,内核关心的唯一 "魔数" 是可执行类型,包括特殊情况下的 #!。其他一切都取决于某个应用程序的决定。 - IMSoP
@IMSoP我不知道eog的确切实现方式,也不知道为什么他们关心文件名。在我看来,这是一个bug。当然,如果文件名为“bmp”,但其内容格式不匹配,那么也会出现错误。当然,每个应用程序都决定如何验证文件,但通常情况下,Linux应用程序不应该依赖于文件名称。顺便说一下,您可以使用“file”命令通过内容检查文件类型。 - Byte Commander
2我对这个句子提出质疑的是:“Linux通过检查前几个字节来确定文件类型。”在这个句子中,你对“Linux”的定义是什么?file实用工具的存在并不能真正证明任何事情;它只是一个有用的工具,可以存在于任何操作系统上。在运行file与使用通配符匹配文件名相比,有什么基本部分使得运行file更加“正确”呢? - IMSoP
请注意,没有扩展名的文件可以与一个程序关联起来。 - isanae

Linux通过文件头中的代码来确定文件类型。它不依赖于文件扩展名来确定使用哪个软件打开文件。
这是我从教育中记得的,请在我错了的情况下纠正我!
这些扩展名只是为人类而设吗?
是的,但有一个例外。
当您与其他依赖于扩展名的操作系统进行交互时,使用这些扩展名是更明智的选择。
在Windows中,打开软件与扩展名相关联。
在Windows中,打开名为"file"的文本文件比打开同名为"file.txt"的文件要困难(每次都需要将文件打开对话框从*.txt切换到*.*)。对于制表符和分号分隔的文本文件也是如此。导入和导出电子邮件(.mbox扩展名)也是如此。
特别是在编写软件时。打开名为"software1"的HTML文件和名为"software2"的JavaScript文件比打开名为"software.html"和"software.js"的文件更困难。
如果Linux中有一个系统,文件扩展名很重要,我会称之为一个错误。当软件依赖于文件扩展名时,这是可以被利用的。我们使用解释器指令来识别文件的类型(文件的前两个字节可以是字符“#!”,构成一个魔术数字(十六进制23和21,即“#”和“!”的ASCII值),通常称为shebang)。
文件扩展名最著名的问题是Windows上的LOVE-LETTER-FOR-YOU.TXT.vbs。这是一个Visual Basic脚本,在文件资源管理器中显示为文本文件。
在Ubuntu中,当您从Nautilus启动一个文件时,会收到一个关于它将要执行的操作的警告。从Nautilus执行一个脚本,它想要启动一些软件,并且应该打开gEdit,显然是一个问题,我们会收到一个警告。
在命令行中,当您执行某个命令时,您可以直观地看到文件的扩展名。如果以.vbs结尾,我会开始怀疑(并不是说.vbs在Linux上可执行。至少不是那么容易;))。

37我完全不明白你在最后一句话中想要表达什么。首先,这是一个隐藏扩展名的问题,而不是拥有扩展名的问题;其次,在Linux中,利用方式是相同的——你给一个二进制文件命名为readme.txt并使其可执行。如果用户执行它,它不会打开编辑器,而是运行代码。从这个角度来看,让扩展名有意义(但不隐藏它们)更安全且更容易解释给非专业用户。还有其他差异(尤其是不从当前目录执行文件),但与扩展名无关。 - techraf
5@techraf 实际上,文件管理器可能会尝试用文本编辑器打开 readme.txt 文件。我刚刚在KDE的海豚文件管理器中尝试过,创建一个添加了可执行权限并将其保存为.txt的shell脚本,然后单击它将使其在Kate中打开。如果我将其重命名为.sh,然后单击它将运行该脚本。 - Bakuriu
文件管理器可能会有误解,我并不是在指文件管理器(这也可以从“当前目录”备注看出来)。事实上,我打算询问作者最后一句话的意思(我承认我是间接地这样做的)。我不确定为什么你提到了我的昵称。你的评论似乎更像是在质疑回答本身中某些主张的有效性(看起来就好像在称呼文件管理器是个错误)。 - techraf
9Linux:由于make是基于依赖文件扩展名的规则构建的,这难道不会使得扩展名的用途超出了仅仅针对人类吗? - bolov
2根据扩展名来打电话,我会称之为一个错误。应该采取的措施是调用并检查命令"file",以查看魔数。@techraf,“如果用户执行了它,它不会打开编辑器,而是运行代码”,这是一个用户问题,而不是系统安全问题。当我们看到README.TXT时,我们使用"more"、"gedit"、"vim"或"nano"来查看它。我们不会执行自述文件。这是Windows的思维方式,在Linux中我们不需要。 - Rinzwind
1@techraf,你做出了太多假设。"看起来它把文件管理器称为一个错误" 不,我没有这样做。Nautilus所做的是正确的。如果你打开一个README.TXT文件,它会扫描魔术数字并提供适当的问题来警告你以何种方式打开它。如果它没有提供以gEdit打开它的选项,而你仍然选择这样做,那么问题就出在你身上,而不是Nautilus身上。它已经完成了它的工作:警告你。再次强调:文件扩展名除了用于让用户可见地看出应该使用什么文件外,不应包含其他内容。 - Rinzwind
3正如其他人所指出的那样,某些文件类型很难通过其内容来定义,例如基于zip存档的许多格式(JAR、ODF、OOXML等)。一个文件也有可能包含在两个上下文中都有效的数据(例如,您可以连接一个zip存档和一个GIF,该文件在两种格式中都有效)。因此,允许用户通过命名约定提供额外信息可以改善用户体验。调用file命令并决定将ILOVEYOU传递给一个存在漏洞的解释器运行并不更安全 - 攻击者可以确定名称和内容。 - IMSoP
3此外,“在Linux中,当您从Nautilus启动一个文件…”应该真正是“在Nautilus中,当您启动一个文件…”,或者可能是“…双击一个文件…”。这与Linux作为内核或整个操作系统完全无关,而只是该特定应用程序所做的用户界面决策。Windows版本的Nautilus可以做出完全相同的决策。 - IMSoP
@IMSoP 没错。我改成了Ubuntu :) (其他系统可能会根据自己的需求更改Nautilus) - Rinzwind
3@IMSoP 不仅仅是“非常困难”,有时候甚至是不可能的。如果 file 不知道如何识别更奇特的文件格式之一,最好希望它有一个附加的扩展名,这样你就可以搜索它了,否则使用那个文件就祝你好运了。 - Thomas
@Rinzwind,我(暗示地)询问了你在回答中提到的一个特定句子的意思。明确地说,为什么你将ILOVEYOU蠕虫的问题归因于文件扩展名的存在。ILOVEYOU欺骗用户执行一个文件。在你的回复中,你明确表示如果用户被欺骗了,那是一个“用户问题而不是系统安全问题”。鉴于此,我对你的意图更加困惑了。如果有人花时间阅读你的回答,思考并(可能不够清楚地)针对一个句子提出具体问题,请友好地予以回应。 - techraf
21这是一个极其错误的答案。Linux 的某些部分使用魔数来确定文件类型。在命令行执行文件。但系统的其他重要组成部分使用文件扩展名来知道应该查看什么,无论是动态链接器(希望 .so 文件)、modprobe、构建系统、插件还是用于 Python、Ruby 等语言的库。许多文件没有魔数,file 命令基于启发式方法而非确定性方法。 - Alan Shutko
2如果Linux中有一个系统,文件扩展名很重要,那我会认为这是一个漏洞。嗯,所以cc的历史实践是一个漏洞吗?我相信C编译器一直依赖于文件扩展名来区分需要传递给cc1.c参数和可以直接传递给ld.o参数。 - Jonathan Cast
4Linux通过文件头中的代码来确定文件的类型"正确"是什么鬼?有什么"文件头中的代码"?在Linux中并不存在这样的代码,也没有这种通用的"文件头"。 - leonbloy
在搜索文件时,检查每个文件的文件头会花费很长时间,尤其是在慢速驱动器上。 - ave
3Linux发行版也需要扩展名来确定文件类型,并且它们确实使用它。试试这个命令:cp /bin/ls ~/readme.txt,然后启动Nautilus并打开这个新文件,它将在文本编辑器中打开。尝试编译一个没有.c扩展名的C程序代码,你会得到错误提示。你还觉得gcc有bug吗? - Alex Jones
从文件扩展名来猜测文件类型比从前几个字节来猜测要容易得多,所以我认为文件扩展名对操作系统来说是相当明显的。 - Alex Jones
如果Linux中有一个系统,文件扩展名很重要,我会称之为一个错误:ipython脚本即使有#!/usr/bin/ipython也需要.ipy扩展名。 - Old Badman Grey
根据这篇帖子,上下文菜单和MIME类型是一个错误? - doug
@doug 是的,但严重程度和影响在这里起到了作用。如果你扫描文件的前几个字节,你仍然需要一个参考映射来匹配文件的内容。Mimetype就是做这个的。通过检查扩展名与mimetype而不是实际文件来识别文件是一种简单快捷的方式。虽然不是正确的方式,但这样做可以节省时间。将一个可执行文件误认为是JPG文件可能会成为入侵你系统的潜在漏洞,因此是一个安全隐患。 - Rinzwind
@Rinzwind 没有一种单一的“正确方式”来确定文件的格式。如果你查看文件的前几个字节并确定它是JPEG格式,并不比查看文件扩展名并得出相同结论更加“真实”。最终,文件格式是一个关于“意图”而不是“数据”的问题:作者或用户打算如何解释这个字节序列。"魔数"和文件扩展名都是猜测这种意图的启发式方法。 - IMSoP

正如其他人所提到的,在Linux中使用解释器指令方法(将一些元数据存储在文件中作为头部或魔数,以便告诉正确的解释器来读取它),而不是Windows所使用的文件扩展名关联方法。
这意味着您可以创建几乎任何名称的文件... 除了一些例外情况。
然而,我想要提出一个警告。
如果您的系统上有一些来自使用文件名关联的系统的文件,这些文件可能没有那些魔数或头部。文件扩展名用于识别能够读取这些文件的应用程序,并且如果您重命名此类文件,可能会遇到一些意外效果。例如:
如果您将文件“我的小说.doc”重命名为“我的小说”,Libreoffice仍然可以打开它,但它将以“无标题”的形式打开,并且您必须再次命名它以便保存(Libreoffice默认添加一个扩展名,因此您将会有两个文件“我的小说”和“我的小说.odt”,这可能会很烦人)。
更严重的是,如果你将一个名为My Spreadsheet.xlsx的文件重命名为My-Spreadsheet,然后尝试用xdg-open My-Spreadsheet打开它,你会得到以下结果(因为它实际上是一个压缩文件):

如果你将一个文件重命名为My Spreadsheet.xls,然后再将其重命名为My-Spreadsheet,当你使用xdg-open My-Spreadsheet打开它时,会出现以下错误信息:

打开位置时出错:没有注册应用程序来处理此文件

(尽管在这两种情况下,如果你使用soffice My-Spreadsheet,它仍然可以正常工作)
然后,如果你将无扩展名的文件重命名为My-Spreadsheet.ods并尝试打开它,你将会得到以下结果:

(修复失败)
而且你将不得不重新添加原始扩展名以正确打开文件(然后可以根据需要转换格式)。
简而言之:
如果您有带有扩展名的非本地文件,请不要删除扩展名,以为一切都会没问题!

4一个新式的MS Office文档(docx,xlsx,pptx等)没有文件扩展名,因为这些文件类型实际上只是普通的ZIP压缩文件,其中包含定义文档内容所需的所有XML文档和媒体文件。ZIP压缩目录的文件格式如今非常常见。 - Byte Commander
1已经有很多很好的答案了,但我注意到还有一个特别针对LibreOffice的问题。你创建一个逗号分隔值(CSV)文件并将其保存为“test.csv”,会弹出一个窗口询问你使用的是什么类型的分隔符(例如,LibreOffice Calc)。如果你将这个文件重命名为“test.cs”,那么LibreOffice的Writer就会打开它。所以,除了上面提到的ZIP示例之外,似乎LibreOffice确实利用了文件扩展名。 - Ray
3Linux文件系统对于文件类型并没有做任何特殊处理,这完全取决于运行在其之上的程序。 - Peter Green
1@PeterGreen 是的,但是这些程序赋予它重要性的事实意味着它并不仅仅是为了人类而存在。例如,经典的MacOS有四字节的“文件类型”和“创建者应用程序”字段,并不是文件名的一部分,因此操作系统和应用程序可以通过这些信息获取所需的所有信息,而无需查看文件扩展名。 - Random832
5@PeterGreen Windows文件系统对文件类型也没有任何特殊处理。图形界面(Windows资源管理器)使用文件扩展名来选择双击时的操作,但从技术上讲,这只是在操作系统之上运行的一个程序,就像Nautilus一样。完全可以编写一个具有这种行为的Linux文件管理器,或者一个检查文件内容的Windows文件管理器。 - IMSoP

我想以与其他答案不同的方式来对待这个问题,并挑战“Linux”或“Windows”与此有任何关系的观念(请耐心等待)。
文件扩展名的概念可以简单地表达为“根据文件名的一部分来识别文件类型的约定”。用于识别文件类型的其他常见约定包括将其内容与已知签名数据库进行比较(“魔数”方法),以及将其作为文件系统上的额外属性存储(原始MacOS中使用的方法)。
由于Windows或Linux系统上的每个文件都有名称和内容,想要知道文件类型的进程可以根据需要使用“扩展名”或“魔数”方法。元数据方法通常不可用,因为大多数文件系统上没有标准的位置来存储此属性。
在Windows上,使用文件扩展名作为识别文件的主要手段有着悠久的传统;最明显的是,在图形文件浏览器(Windows 3.1上的文件管理器和现代Windows上的资源管理器)中,当您双击一个文件时,它会使用文件扩展名来确定要启动哪个应用程序。在Linux(以及更一般地说,基于Unix的系统)上,更多的传统是检查文件内容;最值得注意的是,内核会查看直接执行的文件的开头,以确定如何运行它;脚本文件可以通过以#!开头,后跟解释器路径来指示要使用的解释器。
这些传统影响了为每个系统编写的程序的用户界面设计,但也有很多例外情况,因为每种方法在不同情况下都有利弊。使用文件扩展名而不是检查内容的原因包括:
  • 检查文件内容相对于检查文件名来说是相当昂贵的;所以例如"查找所有名为*.conf的文件"比"查找所有第一行与此签名匹配的文件"要快得多
  • 文件内容可能会产生歧义;许多文件格式实际上只是以特殊方式处理的文本文件,许多其他文件则是特殊结构的压缩文件,为这些文件定义准确的签名可能会很棘手
  • 一个文件可以真正地属于多种类型;一个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系统中没有这样的传统。 - Monty Harder
这是一个更好的答案,但有一个事实错误...通过在开头放置#!,无法使脚本可执行。任何设置了可执行位的文件都可以以多种方式执行。#!/bin/bash和类似的签名只是指定要使用的解释器。如果没有提供这样的签名,则假定使用默认的shell解释器。一个只包含两个单词“Hello World”的文件,但其执行位被设置,将在运行时尝试找到一个“Hello”命令。 - DocSalvager
2@DocSalvager 不错,那个措辞有点笨拙。我稍微改了一下,以明确说明 shebang 并不是使脚本可执行的关键,它只是改变了脚本的执行方式。 - IMSoP

实际上,有些技术确实依赖于文件扩展名,所以如果你在Ubuntu中使用这些技术,就必须依赖于扩展名。以下是一些例子:
- `gcc` 使用扩展名来区分 C 和 C++ 文件。没有扩展名的话,几乎不可能区分它们(想象一个没有类的 C++ 文件)。 - 很多文件(如 `docx`、`jar`、`apk`)只是结构化的 ZIP 归档文件。虽然你通常可以通过内容推断出类型,但并不总是可能的(例如 Java Manifest 在 `jar` 文件中是可选的)。
在这些情况下不使用文件扩展名只能通过一些不太正规的变通方法,并且很容易出错。

你提到编程真不错,但是你对大部分细节都理解错了。gcc 是用于 C 文件的前端,而对于 C++ 文件,你需要使用 g++ 前端或者通过命令行开关来指定语言。更重要的是 make 程序,它决定是否使用 gccg++ 来构建特定的文件 —— 而 make 完全依赖于文件名模式(主要是扩展名)来进行规则匹配。 - Ben Voigt
@BenVoigt 当使用 gcc 编译一个扩展名为 .cc 的文件时,它实际上会被编译为 C++,这在 man gcc 中有记录:“对于任何给定的输入文件,文件名后缀决定了进行什么类型的编译:” 后跟一系列扩展名及其处理方式。 - hvd
1@hvd 如果你没有使用正确的前端,那么可能是默认的库集出了问题。无论如何,make 是一个典型的例子,因为它的所有操作都基于文件扩展名。 - Ben Voigt
2@BenVoigt make也是一个很好的例子,但是gcc同样严重依赖于文件名。这里有一个比.c.cc更清晰的例子:对于C语言,gcc使用后缀来判断它的第一步是预处理(.c),编译(.i),汇编(.s)还是链接(.o)。在这个例子中,我使用了-E-S-c来告诉gcc在哪里停止,但它使用文件名来知道从哪里开始。 gcc something.cc不会链接到正确的C++库,但它会将文件视为C++,这就是为什么许多用户在犯下这个错误时会感到困惑的原因。 - Eliah Kagan

你的第一个假设是正确的:Linux上的扩展名并不重要,只对人类(以及其他关心扩展名的非Unix-like操作系统)有用。文件的类型由文件中的前32位数据确定,这被称为魔数
这就是为什么shell脚本需要#!行 - 告诉操作系统调用哪个解释器。没有它,shell脚本只是文本文件。
至于文件管理器,它们确实想要知道某些文件的扩展名,比如.desktop文件,基本上相当于Windows版本的快捷方式,但具有更多功能。但就操作系统而言,它需要知道文件中的内容,而不是文件名中的内容。

4这并不完全正确。有些程序期望特定的文件扩展名。最常见的例子可能是gunzip,如果文件不叫foo.gz,它就无法解压缩。 - terdon
这是特定软件的实现。在类Unix系统上,大多数实用程序不需要扩展名。 - Sergiy Kolodyazhnyy
8在很大程度上,大多数情况下不会使用文件扩展名。然而,你的第一句话声称它们从不被使用,只对人类有意义,这并不完全准确。例如,"gunzip" 是一个例子,"eog" 是另一个例子。此外,许多工具在没有正确扩展名的情况下无法自动完成名称。我只是说这个问题比"扩展名总是无关紧要"要复杂一些。 - terdon
1有一个小问题:OP问的是关于操作系统的。'gunzip'和'eog'并不是操作系统,而是决定创建自己的限制(在gunzip的情况下)或方法(eog)。但是,“mime类型”是相关的。 - Rinzwind
@Rinzwind 对于什么是和不是“操作系统”,这是一个观点和争论的问题(有时还会引发法律诉讼!)。Linux内核中没有任何需要知道文件是位图的必要,无论是通过文件名还是内容。 - IMSoP
一个魔术数字并不是一个固定大小的字段。 - Random832
@Random832 在Unix内核的上下文中,历史上文件的前两个字节(16位,而不是32位)用于标识可执行格式。请注意,这包括两个字节#! ,其处理程序开始读取以下字节直到新行,然后再决定如何继续。我找到了这篇文章(https://0xax.gitbooks.io/linux-insides/content/SysCall/syscall-4.html ),它详细介绍了当前Linux实现的情况,不再有2字节魔数的显式限制(它始终预先加载文件的128字节)。 - IMSoP
@terdon 我可以让gunzip解压任何我想要的文件,只需不告诉它文件的名称gunzip <foo它会愉快地解压文件。 - Monty Harder
朋友们,就操作系统本身而言,它并不关心扩展名。gunzip是一种特定的软件,它接受特定的参数。楼主问的是扩展名对操作系统是否重要,而不是对任何软件是否重要。我们为什么还要讨论这个问题呢? - Sergiy Kolodyazhnyy
@IMSoP 显然,操作系统并不是一个非常有争议的话题 - 它由内核和几个基本服务组成。gunzipeog是软件,它们绝对不会影响系统的运行方式,而且系统明显可以很好地在没有它们的情况下正常运行。它们也不负责加载其他程序,例如Linux内核或程序加载器。 - Sergiy Kolodyazhnyy
2@Serg 当然,你可以狭义地定义操作系统,并对这个问题给出一个简单的答案。然而,这并不是一个特别有帮助的答案,因为用户在使用计算机时所涉及的绝大部分内容都是你排除在外的软件。请注意,这个问题将“仅限于人类”与“操作系统”进行了对比,我认为他们并不是指“内核”。 - IMSoP
2@Serg “显然,操作系统并不是一个非常有争议的话题。” 哦,需要引用。Canonical 称Ubuntu为“操作系统”。 你说操作系统是由“内核和几个基本服务”组成的,但你没有说明你认为哪些是这些“基本服务”。我特别想知道你认为systemd的哪些部分是操作系统组件,哪些不是。这个回答隐含地使用了一个模糊的“操作系统”的概念,并且与大多数人在*nix圈子中所指的含义不同。 - Eliah Kagan

这个评论回答太长了。
记住,即使是“扩展名”也有很多不同的意思。
你所说的似乎是在.之后的三个字母。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文件。尽管如此,扩展名仍然具有意义,并且在“计算机层面”上仍然用于许多事情。

2Windows现在不再局限于x.3的命名规则,您还可以使用更长的扩展名,例如.doxc, .torrent, .part等。只是在8.3命名仍然存在的时候,许多文件格式和扩展名已经被定义,后来的格式大多只是简单地采用了使用最多3个字母的约定。 - Byte Commander
1我不明白".conf"、".c"等与"8.3格式"有什么"不同的含义"。文件扩展名的概念可以简单地表达为"根据文件名的一部分来识别文件类型的约定"。即使是DOS/Win3.1也不需要正确的扩展名(你可以将一个Word文档命名为"STUPIDN.AME",然后在WinWord中使用Ctrl-O打开它)。只是一些系统(例如Windows上的双击、gzip、您的Makefile等)可能会编写成使用这种约定来对每个文件采取正确操作的假设。 - IMSoP
@ByteCommander 是的,但扩展名仍然决定了所使用的应用程序。我不确定如何编辑答案以反映这一点。 - coteyr
@IMSoP 你说得对,如果你打开一个程序,你可以在该程序中打开任何文件。然而,操作系统会将STUPID.AME视为ACT!电子邮件系统库。例如,除非以.exe、.com、.bat或者.maybe .dll结尾,否则你无法启动一个程序。如果你将foo.exe重命名为foo.txt,并询问系统foo.txt是什么类型的文件,它会告诉你这是一个文本文件。 - coteyr
2@coteyr 再说,这都取决于我们对"操作系统"的理解。文件管理器肯定会查找注册表键来判断"AME",并告诉我"foo.txt"是一个文本文件。但在命令提示符下运行dir却不会告诉我任何信息;它根本不关心。在两个操作系统中,执行文件肯定是个例外;如果问题只限于这些情况,答案将是DOS/Windows 仅仅关心名称,而Unix/Linux 仅仅关心执行权限和文件前几个字节。除此之外,总有一些应用程序选择遵循某种约定。 - IMSoP
2@coteyr 你忘记了 Windows 3.1 及以上版本中的 *.scr(屏幕保护程序二进制文件)。话虽如此,即使在 DOS/Windows 系统中,文件扩展名对于可执行文件也仅仅是一种便利性。具体情况很大程度上取决于你对 "操作系统" 的界定,在任何情况下,你都可以将二进制文件加载到内存中并自行跳转到其中,完成通常由操作系统处理的工作。在 MS-DOS 中,如果你查看 command.com,我非常确定那里有类似 EXE COM 的列表,你可以编辑它以便在未指定扩展名时找到其他扩展名(这并不意味着这样做是个好主意,提醒你注意)。 - user