为什么不将.txt文件设为可执行文件,而不是.sh文件来运行脚本呢?

我想知道为什么需要将可执行命令放在一个 .sh 文件中以创建一个单一的脚本,因为我可以通过将命令放在一个 .txt 文件中并使用 chmod 命令使其可执行来实现相同的功能。

我猜这可以使用任何文件扩展名来完成。所以,我对使用 .sh 扩展名的必要性感到很困惑。非常感谢您的帮助。


19Unix传统上不关心文件扩展名。所以你是正确的 - 这并不重要。这只是为了让读者明显地知道它是一个shell脚本。 - vidarlo
8在Linux中,文件扩展名并不以任何实际方式被操作系统使用。仅仅给一个文件添加.sh扩展名只是告诉用户它是一个shell脚本,而不是其他类型的文件,如Python或Perl脚本。个人而言,我不给我的脚本添加扩展名。 - doneal24
2只需要告诉你或任何其他人,这是一个shell脚本。如果你不在意告诉哪些.txt文件是要运行的脚本,哪些是要在编辑器中打开的文本,可以随意将所有文件命名为.txt! - daboross
2如果所有的文件都以.txt后缀结尾,那么你并没有帮助自己(或其他人)理解每个文件的用途。 - leftaroundabout
请参阅https://askubuntu.com/questions/413150/is-it-bad-practice-for-folder-name-to-contain-dot-how-about-file-name-with/413157?s=1|23.0354#413157。 - user68186
1这个问题与它所谓的重复问题相似,但那个问题实际上并没有回答这个问题。 - Kenny Evitt
另外,如果你正在编写一个Bash脚本,也就是一个在Bash shell中运行或由Bash解释器执行的脚本,你可以使用*.bash*扩展名来表示它不打算(或无法)由Bourne shell (sh)执行。 - Kenny Evitt
2个回答

没有必要让文件扩展名与特定内容匹配,正如你正确发现的那样。
在类Unix系统中,文件类型通常是根据文件内容(即前几个字节中的“魔数”或其他特征结构)而不是根据文件名来确定的。你也可以完全省略扩展名,这在可执行文件中经常这样做。
检查一下`file`命令,它会显示关于文件类型的信息。
对于可执行脚本,系统期望在第一行有一个所谓的“shebang”,它看起来像这样:
#!/usr/bin/env python3

并指示使用脚本文件作为参数来运行的解释器程序。如果您执行没有这样的shebang的文本文件,它将使用您的默认shell(即Bash)尝试解释它。

因此,在Unix/Linux系统上,文件名扩展名主要是对人类用户的提示(但不保证)以便快速识别特定文件所包含的内容。这也是一个可以帮助查找文件更快的约定。

请注意,有一些例外情况,其中名称和扩展名很重要(例如,一些系统配置文件必须遵循命名约定,或者许多图像查看器和编辑器还需要扩展名来指示文件类型)。

您也可以参考文件扩展名在操作系统中有什么用途吗?


3在命令行中,文件扩展名并不重要,但在图形用户界面操作系统的世界中,你基本上需要它们来确保双击功能正常运作。 - BallpointBen
@BallpointBen 两个点之间没有关联。即使在 GUI 下,文件的“类型”可以作为元数据存储,并且可以触发特定的执行操作,而与扩展名无关。MacOS 没有文件名扩展名,但它很好地适应了 GUI... - Patrick Mevzek
1@PatrickMevzek MacOS怎么没有扩展名?我已经启用了显示扩展名,并且所有文件都有扩展名。是我漏掉了什么吗?我对MacOS平台还很陌生。 - Ciprian Tomoiagă
@CiprianTomoiagă MacOS是一种UNIX系统,正如您所注意到的那样,它使用了典型的UNIX文件扩展约定。 - Teemu Leisti
1@CiprianTomoiagă 你可以随意给你的文件命名,操作系统不需要扩展名来正确地处理它们。例如,可以参考这个链接:https://www.howtogeek.com/192628/mime-types-explained-why-linux-and-mac-os-x-dont-need-file-extensions/ - Patrick Mevzek
@PatrickMevzek但是如果您与Windows用户共享文件,请不要这样做。 - barbecue
1@烧烤 以最低公共分母为目标...这样做会有什么问题吗 :-) (例如通过电子邮件附件攻击,称为something.com.txt,并进行技巧操作以跳过.txt,因为在Windows领域中.com具有特定含义)。确实,为了互操作性,文件扩展名可能是一个好的实践。但必须学习到,这显然是DOS基本引入的缺陷,并且各种操作系统可以完全愉快地使用没有扩展名的文件。 - Patrick Mevzek
@PatrickMevzek 假文件扩展名之所以有效,是因为在Windows和Mac OS上,默认情况下隐藏了扩展名。这是一个愚蠢到极点的默认设置,充满了失败,但却一直存在。 - barbecue
@barbecue 你说得没错,但也要记住,“我们”(Unix/Linux用户)有自己的愚蠢之处,比如以“.”开头表示隐藏文件,这几乎完全属于同一问题类别,同样是纯粹的失败制造(只是细节有所不同)。 - jrw32982
除了Windows还有一个单独的“隐藏”标志用于文件。还有一个单独的“系统”标志用于文件,两者都可以隐藏文件,但是根据你使用的用户界面不同,隐藏的方式也不同。 随意截断文件名是一种更加愚蠢的行为。 - barbecue

在UNIX/Linux文件名中,不存在所谓的“扩展名”或“类型”。
正如其他人指出的那样,可以使用file命令来查找“类型”,前提是您的系统上有相关的魔术信息。 UNIX/Linux文件名通常可以包含任何可用字符,但通常最好使用某种约定来命名,以便人和机器都能对内容(以及内容的使用)进行判断。
举个例子,我经常在文件名的第一个字符使用逗号来表示临时文件,而不是在文件名末尾使用类似于“.tmp”这样的字符串。结果是一样的,都是包含数据的文件,只是该数据仅在短时间内需要。这样的命名不需要在其中包含“.”或“tmp”这样的字符串。这在解析文件名列表时有时会有优势。但这只是我的约定,其他人可能会决定采用另一种约定,甚至将“.tmp”作为临时文件的命名约定。
所以,我的回答是,在UNIX/Linux中并不存在所谓的文件扩展名,只有一组通常看起来像其他操作系统和文件系统中使用的文件扩展名的约定。

就我个人而言,我也使用一种非标准的约定。以“.”开头的脚本文件是为了让shell执行(它们在子shell中无法有意义地运行)。相应地,我在使用ls命令的别名/脚本中禁用了默认的“初始点=隐藏文件”的约定,这样我就可以看到所有的文件,包括“隐藏”的文件。同样,在Windows上,我禁用了“隐藏文件扩展名”的设置。 - jrw32982