为什么需要在脚本文件的开头加上#!/ bin / bash?

问题描述 投票:432回答:9

我之前制作了Bash脚本,并且在开始时它们都运行良好。把它放进去有什么意义?会有什么不同吗?

另外,你怎么发音#?我知道!的发音是“爆炸”。

#!是如何发音的?

linux bash scripting shebang
9个回答
387
投票

这是一个约定,所以* 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下,将后缀与文件类型相关联仅仅是一种约定,而不是“规则”。可执行文件可以是二进制程序,也可以是一百万种脚本类型中的任何一种。因此需要#!/bin/bash


123
投票

更准确地说,shebang #!,当它是可执行文件(x mode)文件的前两个字节时,由execve(2)系统调用(执行程序)解释。但POSIX specification for execve没有提到shebang。

它必须后跟解释器可执行文件的文件路径(BTW甚至可以是相对的,但通常是绝对的)。

在用户的not so nice中找到解释器(例如python)的一个很好的技巧(或者可能是$PATH)是使用env程序(总是在所有Linux上的/usr/bin/env),例如

 #!/usr/bin/env python

任何ELF可执行文件都可以是解释器。如果你愿意,你甚至可以使用#!/bin/cat#!/bin/true! (但这通常是无用的)


47
投票

它被称为shebang。在unix中,#被称为sharp(如音乐)或hash(如twitter上的hashtags),以及!被称为爆炸。 (你实际上可以用!!引用你以前的shell命令,叫做bang-bang)。所以当放在一起时,你会得到haSH-BANG,或者shebang。

#之后的部分!告诉Unix用什么程序来运行它。如果未指定,它将尝试使用bash(或sh,或zsh,或任何你的$ SHELL变量),但如果它在那里它将使用该程序。另外,#是大多数语言的注释,因此在后续执行中会忽略该行。


16
投票

shebang是加载程序使用程序的指令,当您尝试执行该程序时,该程序在#!之后指定为该文件的解释器。因此,如果您尝试运行名为foo.sh的文件,其顶部有#!/bin/bash,则运行的实际命令是/bin/bash foo.sh。这是为不同程序使用不同解释器的灵活方式。这是在系统级实现的,用户级API是shebang约定。

同样值得一提的是,shebang是一个magic number--一个人类可读的,它将文件标识为给定解释器的脚本。

即使没有shebang,你关于它“工作”的观点仅仅是因为有问题的程序是为你正在使用的shell编写的shell脚本。例如,你可以写一个javascript文件,然后把一个#! /usr/bin/js(或类似的东西)用于javascript“Shell脚本”。


16
投票

操作系统使用默认shell来运行shell脚本。所以在脚本开头提到shell路径,你要求OS使用那个特定的shell。它对portability也很有用。


14
投票

每个发行版都有一个默认shell。 Bash是大多数系统的默认设置。如果您碰巧在具有不同默认shell的系统上工作,那么如果脚本是针对Bash编写的,则脚本可能无法正常工作。

多年来,Bash从kshsh获取代码。

添加#!/bin/bash作为脚本的第一行,告诉操作系统调用指定的shell来执行脚本中的命令。

#!通常被称为“hash-bang”,“she-bang”或“sha-bang”。


9
投票

它被称为shebang。它由一个数字符号和一个感叹号字符(#!)组成,后跟解释器的完整路径,如/ bin / bash。 UNIX和Linux下的所有脚本都使用第一行指定的解释器执行。


1
投票

例如,您还会在#!/ bin / bash之后看到一些其他参数 #!/bin/bash -v -x 阅读本文以获得更多想法。 https://unix.stackexchange.com/questions/124272/what-do-the-arguments-v-and-x-mean-to-bash


0
投票

对于使用不具有该库的不同系统的人来说,它可能是有用的。如果未声明并且您的脚本中有一些该系统不支持的函数,则应声明#/ bin / bash。我在工作之前遇到过这个问题,现在我只是把它作为一种练习。

© www.soinside.com 2019 - 2024. All rights reserved.