为什么你需要把#!/ bin / bash放在脚本文件的开头?
我以前做过Bash脚本,一开始没有这个,它们都运行良好。 有什么意思呢? 会有什么不同?
另外,你如何发音#
? 我知道!
发音为“bang”。
#!
怎么样#!
发音?
这是一个约定,所以* nix shell知道要运行什么样的解释器。
例如,旧版本的ATT默认为sh (Bourne shell),而旧版本的BSD默认为csh (C shell)。
即使在今天(大多数系统运行bash, “Bourne Again Shell” ),脚本也可以是bash,python,perl,ruby,PHP等。例如,您可能会看到#!/bin/perl
或#!/bin/perl5
。
PS:感叹号( !
)被亲切地称为“砰” 。 shell注释符号( #
)有时被称为“散列” 。
PPS:请记住,在* nix下,将后缀与文件types关联仅仅是一种约定 ,而不是“规则” 。 可执行文件可以是二进制程序,也可以是百万个脚本types中的任何一种。 因此需要#!/bin/bash
。
更准确地说, shebang #!
,当它是可执行文件 ( x
模式 )的前两个字节时,由execve(2)系统调用(执行程序)解释。 但是execve
POSIX规范并没有提到shebang。
它必须跟着一个解释器可执行文件的path(BTW甚至可以是相对的,但通常是绝对的)。
在用户的$PATH
find一个解释器(例如python
)的一个很好的技巧是(或者不是那么好 ),就是使用env
程序(总是在所有Linux上的/usr/bin/env
)
#!/usr/bin/env python
任何ELF可执行文件都可以是一个解释器。 你甚至可以使用#!/bin/cat
或#!/bin/true
如果你想! (但那往往是无用的)
这就是所谓的“ 在unix中,#被称为尖锐(如音乐中)或哈希(如Twitter上的主题标签),以及! 被称为砰。 (你可以用!!来引用你以前的shell命令,叫做bang-bang)。 所以放在一起时,你会得到hash-bang或者shebang。
#之后的部分! 告诉Unix什么程序来运行它。 如果没有指定,它会尝试使用bash(或者sh,或者zsh,或者你的$ SHELLvariables),但是如果它在那里,它将使用该程序。 另外,#是大多数语言中的注释,所以在随后的执行中该行被忽略。
shebang是加载程序使用#!
之后指定的程序的指令#!
作为当你尝试执行它的文件的解释器。 所以,如果你试图运行一个名为foo.sh
的文件,该文件的foo.sh
有#!/bin/bash
,那么运行的实际命令是/bin/bash foo.sh
这是为不同的程序使用不同解释器的灵活方式。 这是在系统级别实现的,用户级API是shebang约定。
另外值得一提的是,shebang是一个神奇的数字 – 一个可读的文件,它将文件标识为给定解释器的脚本。
即使没有使用shebang,你的关于“正在工作”的观点也只是因为有问题的程序是一个为你使用的shell编写的shell脚本。 例如,你可以很好地写一个JavaScript文件,然后把一个#! /usr/bin/js
#! /usr/bin/js
(或类似的东西)有一个JavaScript“Shell脚本”。
操作系统使用默认的shell来运行你的shell脚本。 所以在脚本的开头提到shellpath,你就是要求操作系统使用那个特定的shell。 这对便携性也很有用。
每个发行版都有一个默认的shell。 Bash是大多数系统的默认设置。 如果您碰巧在具有不同默认shell的系统上工作,那么脚本可能无法正常工作(如果它们是针对Bash编写的)。
Bash多年来一直在从ksh
和sh
代码中进化出来。
添加#!/bin/bash
作为脚本的第一行,告诉操作系统调用指定的shell
来执行脚本中的命令。
#!
通常被称为“砰砰砰砰”,“啪啪啪”或“沙屁”。
它被称为shebang 。 它由一个数字符号和一个感叹号字符(#!)组成,然后是解释器的完整path,例如/ bin / bash。 UNIX和Linux下的所有脚本都使用第一行指定的解释器执行。
对于使用不具有该库的其他系统的人来说可能是有用的。 如果没有声明,并且脚本中有一些function不受该系统支持,则应该声明#/ bin / bash。 在工作之前,我遇到了这个问题,现在我只是把它作为一个练习。