这是一种约定,让*nix shell知道要运行哪种解释器。
例如,旧版的ATT默认使用Bourne shell(sh),而旧版的BSD默认使用C shell(csh)。
即使在今天(大多数系统运行bash,“Bourne Again Shell”),脚本也可以是bash、python、perl、ruby、PHP等等。例如,你可能会看到#!/bin/perl
或#!/bin/perl5
。
PS:
感叹号(!
)亲切地被称为“bang”。Shell注释符号(#
)有时被称为“hash”。
PPS:
请记住,在*nix下,将后缀与文件类型关联仅仅是一种惯例,而不是一条“规则”。可执行文件可以是二进制程序,也可以是数百万种脚本类型和其他东西。因此需要使用#!/bin/bash
。
execve(2)
系统调用时由kernel解释的。因此,shebang是kernel的惯例,而不是shell的惯例。 - Basile Starynkevitch#!
出现在可执行文件(x
mode)的前两个字节时,它会被execve(2)系统调用解释(该调用执行程序)。但是POSIX规范中的execve
没有提及shebang。一个好用的技巧(或者也许是不太好用的)来查找用户 $PATH
中的解释器(例如python
)是使用 env
程序(在所有 Linux 上始终位于 /usr/bin/env
),如下所示。
#!/usr/bin/env python
#!/bin/cat
或者#!/bin/true
(但这通常是没有用的)。#!/usr/bin/env bash -x
。我该怎么做? - indianwebdevil#!/usr/bin/env bash -x
后添加参数即可。 - indianwebdevilbash
is almost always at /bin/bash
so your shebang should be #!/bin/bash -x
- Basile Starynkevitch这个被称为 shebang。在Unix语言中,#号被称为sharp(尖音符),或者hash(如Twitter上的标签),!号被称为bang。你实际上可以通过两个感叹号(!!),也就是bang-bang来引用之前的shell命令。因此,当它们结合在一起时,你得到哈希-叹号(hash-bang),或者 shebang。
#!后面的部分告诉Unix要使用哪个程序来运行它。如果没有指定,它将尝试使用bash(或sh、zsh,或任何你的$SHELL变量值是什么的程序),但是如果指定了,它将使用该程序。此外,在大多数语言中,#是注释符号,所以这一行在后续执行中将被忽略。
execve(2)
系统调用不使用$SHELL
变量。解释shebang的是内核。 - Basile Starynkevitch每个发行版都有一个默认的shell。Bash是大多数系统上的默认值。如果你碰巧在一个具有不同默认shell的系统上工作,则如果脚本是针对Bash编写的,它们可能无法按预期工作。
Bash随着时间的推移已经发展起来了,从ksh和sh中获取代码。
在您的脚本的第一行添加#!/bin/bash
,告诉操作系统调用指定的shell
来执行接下来的命令。
#!
通常被称为“哈希-惊叹号”,“she-bang”或“sha-bang”。
Shebang是一种指令,告诉加载器在尝试执行文件时使用在#!
后指定的程序作为解释器。因此,如果您尝试运行名为foo.sh
的文件,并且该文件顶部有#!/bin/bash
,则实际运行的命令是/bin/bash foo.sh
。这是一种灵活使用不同解释器处理不同程序的方式。这是在系统级别实现的,用户级别的API是shebang约定。
值得知道的是,shebang是魔数之一,它能够以人类可读的方式识别文件作为给定解释器的脚本。
您提到即使没有shebang,“工作”也是因为相关程序是针对您正在使用的相同shell编写的shell脚本。例如,您可以编写JavaScript文件,然后加上#! /usr/bin/js
(或类似内容)来将其作为JavaScript“Shell脚本”使用。
这被称为shebang。它由一个井号和一个感叹号字符(#!)组成,其后跟解释器的完整路径,例如/bin/bash。在UNIX和Linux下,所有脚本都使用在第一行指定的解释器来执行。
Bash标准是Linux中众多可用shell中的一种。
Shell是一个命令行解释器,接受并运行命令。
Bash通常是大多数Linux发行版中的默认shell。这就是为什么bash与shell是同义词。
Shell脚本通常具有基本相同的语法,但有时也会有所不同。例如,Zsh中的数组索引从1开始,而在bash中则从0开始。如果一个脚本是为Zsh shell编写的,并且包含数组,则在bash中无法正常工作。
为了避免出现不愉快的意外,您应该告诉解释器,您的shell脚本是为bash shell编写的。怎么做呢?
只需在您的bash脚本开始处添加 #!/bin/bash。
此外,您会在#!/bin/bash之后看到一些其他参数,例如
#!/bin/bash -v -x
阅读此内容以获取更多想法。
https://unix.stackexchange.com/questions/124272/what-do-the-arguments-v-and-x-mean-to-bash。
对于使用没有该库的不同系统的人来说,这可能非常有用。如果没有声明并且您的脚本中有一些该系统不支持的函数,则应该声明#/bin/bash。我曾经在工作中遇到过这个问题,现在我只是将其包含为一种惯例。
./yourscript.extension
(例如./helloworld.py
或./helloworld.sh
),它将查找顶部的解释器,即#!/bin/python
或!#/bin/bash
,而当像python helloworld.py
这样执行脚本时,第一行将不被观察,因为它被注释掉了。所以这是 shell/kernel 的一个特殊序列。 - Jacqlyn