什么是Bash文件扩展名?


82

我已经在文本编辑器中编写了bash脚本,我将该脚本另存为什么扩展名,以便可以作为bash脚本运行?我创建了一个脚本,该脚本在理论上应该启动ssh服务器。我想知道如何在单击脚本后使脚本执行。我正在运行OS X 10.9.5。


4
Shell脚本不需要任何特定的扩展名。只需将其执行为bash myscript
anubhava 2015年

7
它通常是.sh,但扩展名根本不需要存在。Linux不是Windows。将解释您的脚本的程序在其第一行中确定,应该为#!/bin/bash。它甚至可以包含参数。
Havenard'1

1
@anubhava如果我只是双击它而不真正输入“ bash myscript”,我将如何执行我的脚本
Amedeo 2015年

2
@Amedeo将以行开头的文件#!/bin/bash
Havenard 2015年

Answers:


106

与其他答案不同,有一个通用约定将.sh扩展名用于shell脚本-但这不是有用的约定。最好不要使用任何扩展名。可以说这foo.sh是一个shell脚本的优点是因为它的名称很少,而且您为它付出了很多灵活性。

为了使bash脚本可执行,它需要在顶部有一个shebang行:

#!/bin/bash

并使用该chmod +x命令,以便系统将其识别为可执行文件。然后,需要将其安装在列出的目录之一中$PATH。如果调用了脚本,则foo可以在shell提示符下键入来执行它foo。或者,如果它位于当前目录(临时脚本的常用目录)中,则可以键入./foo

外壳程序和操作系统都不关注文件名的扩展名。它只是名称的一部分。通过给它一个特殊的扩展名,您可以确保使用它的任何人(用户或另一个脚本)都不必关心它的实现方式,无论它是shell脚本(sh,bash,csh还是其他)。 ,Perl,Python或Awk脚本或二进制可执行文件。该系统经过专门设计,因此可以调用解释的脚本或二进制可执行文件,而无需了解或关心其实现方式。

类似UNIX的系统始于纯文本命令行界面。稍后添加了KDE和Gnome之类的GUI。在GUI桌面系统中,通常可以通过例如双击引用该程序的图标来运行该程序(同样,它是脚本还是二进制可执行文件)。通常,这会丢弃程序可能输出的所有输出,并且不允许您传递命令行参数;它比从shell提示符运行它的灵活性要差得多。但是对于某些程序(主要是GUI客户端),它可能更方便。

最好从命令行(而不是从GUI)学习Shell脚本。

(某些工具确实注意文件扩展名。例如,编译器通常使用扩展名来确定代码的编写语言:.c对于C,.cpp对于c ++等。此约定不适用于可执行文件。)

请记住,UNIX(和类似UNIX的系统)不是Windows。MS Windows通常使用文件扩展名来确定如何打开/执行文件。二进制可执行文件需要.exe扩展。如果您在Windows下安装了类似UNIX的外壳程序,则可以配置Windows将.sh扩展名识别为外壳程序脚本,然后使用该外壳程序将其打开。Windows没有#!约定。


2
我的目标是您在第四段中提到的内容。单击指向脚本的图标时,运行脚本。
Amedeo,2015年

2
@Amedeo:那么这取决于您的桌面环境。在我使用的脚本中(在Ubuntu下为Cinnamon),双击可执行脚本的图标会提示我在终端中运行它,在编辑器中显示它,或者在没有终端的情况下运行它。不管文件扩展名是什么,它都会这样做。
基思·汤普森

3
(Necro)如果省略扩展名,则不能再有一个同名文件夹。因此,例如,您具有deploy.sh(或deploy.bash)和一个文件夹deploy,以及其他部署逻辑。如果将脚本重命名为简单脚本,deploy则会导致名称冲突。对文件或文件夹进行不同的命名会损害可管理性,并可能会对文件排序(ls在编辑器中等)造成损害。当然,shebang最终是决定因素。但是文件扩展名确实有其应有的地位。
卡福索(Kafoso),

2
@Kafoso:我认为我从来没有需要拥有相同名称的脚本和目录。如果这样做,我可能会调用目录Deploy,尽管在复制到不区分大小写的文件系统时可能会导致问题。
基思·汤普森

2
在Mac上,双击文件始终会在默认应用程序中打开它们。因此,进行.sh扩展使脚本在所需的编辑器中打开很有帮助。如果您想在双击时运行脚本,请给它.command扩展名,双击后它将在终端中运行。
BallpointBen

17

您不需要任何扩展名(或者您可以选择任意扩展名,但这.sh是一个有用的约定)。

您应该使用来启动脚本#!/bin/bashexecve(2) syscall可以理解第一行),并可以使文件可执行chmod u+x。因此,如果您的脚本位于某个文件中$HOME/somedir/somescriptname.sh,则需要输入一次

 chmod u+x  $HOME/somedir/somescriptname.sh

在一个终端。有关命令,请参见chmod(1 ;有关系统调用,请参见chmod(2)

除非您输入整个文件路径,否则应将该文件放在您提到的目录中PATH(请参阅environ(7)execvp(3)),~/.bashrc如果您的登录shell是,则可以在其中永久设置该目录bash

顺便说一句,您可以使用其他语言编写脚本,例如,以Python开头的脚本#!/usr/bin/python,或以Ocaml开头的脚本,#!/usr/bin/ocaml...

通过双击(关于什么?您没有说!)执行脚本是一个桌面环境问题,并且可能是桌面特定的(与Kde,Mate,Gnome,....或IceWM或RatPoison可能不同)。也许阅读EWMH规格可能会帮助您获得更好的图像。

也许使您的脚本具有可执行性,chmod可能使其在桌面上可单击(显然,在MacOSX上为Quartz)。但是,您可能应该使它提供一些视觉反馈。

而且几台计算机没有任何台式机,包括使用ssh远程访问它时所拥有的台式机。

我不认为通过单击运行Shell脚本是一个好主意。您可能希望能够为您的Shell脚本提供参数(以及如何通过单击来执行此操作?),并且应该注意其输出。如果您能够编写Shell脚本,则可以在终端中使用交互式Shell。那是使用脚本的最佳,最自然的方式。好的交互式外壳程序(例如zshfish或最新的外壳程序bash)具有美味且可配置的自动完成功能,您无需键入太多内容(学习使用tab键盘的键)。另外,脚本和程序通常是复合命令(管道等)的一部分。

PS。我从1986年开始使用Unix,从1993年开始使用Linux。我从来没有通过单击来启动自己的程序或脚本。我为什么要?


3
好的,我已经在文本编辑器中创建了脚本。我将文件保存到桌面。当我单击保存在桌面上的脚本时,我希望它在我单击它时实际运行。
Amedeo,2015年

6
我不知道您的桌面是什么(KDE,Gnome,MATE等)。我强烈建议您在终端中使用命令行,尤其是运行脚本(您可能想给它们一些参数;如何在桌面上这样做?)。如果您能够编写Shell脚本代码,则应该可以在终端中交互使用Shell
Basile Starynkevitch 2015年

2
我的观点是,如果您正在编写Shell脚本,则应养成在终端中使用命令行的习惯。
Basile Starynkevitch 2015年

2
我了解,这是我正在工作的项目。我希望脚本在单击后执行。我试图避免使用终端运行脚本。
Amedeo,2015年

3
我会使用chmod +x而不是chmod u+x,除非有特定原因将可执行性限制为所有者。
基思·汤普森

2

我知道现在这已经很老了,但是我觉得这增加了这个问题的要求。

如果您在Mac上并且希望能够通过双击运行脚本,则需要使用.command扩展名。与之前相同,使文件可执行chmod -x

如前所述,这实际上并不是那么有用。


1

只是.sh

像这样运行脚本:

./script.sh

编辑:就像anubhava所说,扩展名并不重要。但是出于组织的原因,仍然建议使用扩展名。


6
如果您正在运行脚本,通常没有理由关心它的内容。bash脚本和二进制可执行文件以相同的方式执行。在.sh可执行脚本中添加后缀通常是毫无用处的。
基思·汤普森

1
是的,但是正如我在编辑中所说的那样-组织脚本是一种惯例-不能吗?
马克·安东·达门

4
我确实看到了很多带有.sh扩展名的脚本(带有扩展名的脚本很少.bash),但是我不相信它完全有用。如果我命名了脚本foo.sh,后来又决定在Perl中重新实现它,则可以更改名称(并编辑使用该脚本的所有内容),也可以使用误导性的扩展名保留它。如果我命名的话foo,我没有这个问题。
基思·汤普森

1

TL; DR-如果脚本的用户(不一定是开发人员)正在使用GUI界面,则取决于他们使用的文件浏览器。MacOS的Finder将需要.sh扩展名才能执行脚本。但是,Gnome Nautilus可以正确识别带有或不带有.sh扩展名的脚本。

我知道已经多次说过在bash脚本上使用扩展名的理由和反对,但是关于为什么不使用扩展名的原因并没有那么多,但是我认为这是一个很好的经验法则。

如果您是那种跳入bash并退出bash并通常使用终端的类型,或者正在为不使用终端的其他人开发工具,请.sh在bash脚本上添加扩展名。这样,该脚本的用户可以选择在GUI文件浏览器中双击该文件以运行该脚本。

如果您是主要负责终端中所有或大部分工作的类型,请不要在您的bash脚本上添加任何扩展名。假设您已经设置~/.bashrc文件以直观地将脚本与目录区分开,那么它们在终端中将毫无用处。

编辑:

在带有4个测试文件的Gnome Nautilus文件浏览器中(每个文件都具有要执行的文件的权限),使用愚蠢的bash命令打开终端窗口(gnome-terminal):

  1. #!/bin/bash第一行没有扩展名的文件。

    双击文件即可。

  2. 第一行带有.sh扩展名的文件#!/bin/bash

    双击文件即可。

  3. 没有扩展名且#!/bin/bash第一行没有的文件。

    它通过双击文件来工作...从技术上讲,但GUI并未表明它是一个shell脚本。它说这只是纯文本文件。

  4. 第一行带有.sh扩展名的文件#!/bin/bash

    双击文件即可。

但是,正如Keith Thompson明智地指出,在此答案的注释中,依靠使用.sh扩展名而不是文件第一行的bash shebang,#!/bin/bash可能会引起问题。

但是,还有一个,我记得当我以前使用MacOS时,即使没有.sh扩展也不能正确地敲打(是一个单词?)bash脚本,也无法从MacOS的GUI运行。我希望有人在评论中对此进行纠正。如果是这样,则可以证明至少有一个文件浏览器可以解决.sh扩展问题。


您使用哪种GUI文件浏览器(或更相关地,您的用户使用什么)?它是否使用扩展名来决定如何运行脚本?
基思·汤普森

好吧,我经验最丰富的平台是MacOS。在Finder中,用户决定将哪些应用程序与哪个扩展名相关联。现在,我在Linux上使用Gnome,但是我还没有尝试过Gnome的Nautilus文件浏览器如何与没有扩展名的文件交互。
瑞安·哈特

如果您有一个带有.sh后缀且#!/bin/bash在第一行的可执行脚本,是否将使用GUI文件浏览器sh来调用它(忽略shebang)?如果是这样,可能会引起一些问题。(答案可能因不同的浏览器而异。)
Keith Thompson

那里的好点。我已经用我刚才做的一些实际测试更新了上面的答案。
瑞安·哈特

有趣,但是……您说它“有效”。对于这4个测试用例中的每一个,最好知道它是使用/bin/bash还是调用的/bin/sh(后者是没有shebang的脚本的默认值)。如果/bin/sh是的符号链接/bin/bash(这是很常见的),则可以通过查看的值来判断$0。(此外,如果bash在sh设置时被调用POSIXLY_CORRECT=y。)
Keith Thompson
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.