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

nod*_*nja 459 linux bash scripting shebang

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

另外,你怎么发音#?我知道那个!发音是"爆炸".

怎么#!发音?

pau*_*sm4 405

这是一个约定,所以*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.

  • shebang不是*shell*约定,它在处理`execve(2)`syscall时由*kernel*解释; 所以shebang是一个*kernel*约定,而不是shell. (83认同)
  • 此外,如果文件没有扩展名,它可以帮助像Vim这样的编辑者确定语法高亮的语言.如果没有shebang,Vim将显示与纯文本文件相同的bash脚本. (9认同)
  • 我已经看到了这个问题的许多答案,但没有真正的解释 - 但你答案的最后部分“_可执行文件可以是二进制程序,也可以是一百万个脚本类型中的任何一个,也可以是其他东西。因此需要 #! /bin/bash._”确实做到了 (3认同)
  • 所以..._ hash-bang-slash-bin-slash-bash_? (2认同)

Bas*_*tch 125

更确切地说,当它是可执行(模式)文件的前两个字节时,shebangexecve(2)系统调用(执行程序)解释.但是POSIX规范并没有提到shebang.#!x execve

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

在用户中找到解释器(例如)的一个好方法(或者可能不是那么好)是使用程序(总是在所有Linux上),例如python$PATHenv/usr/bin/env

 #!/usr/bin/env python
Run Code Online (Sandbox Code Playgroud)

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

  • 有关`#!/ usr/bin/env` hack的讨论,请参阅[this question](http://unix.stackexchange.com/q/29608/10454). (8认同)

aus*_*ard 47

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

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

  • 如果我已经在 bash 中,它是否会在看到 #!/bin/bash 时启动另一个 bash 实例?如果我已经在 bash 中而我将其排除在外怎么办?有什么区别吗? (2认同)
  • @javascriptninja以任何一种方式启动一个新的bash shell.在bash的情况下,只要你已经使用bash,就没有任何区别.如果(a)你需要运行不仅仅是shell的东西,比如python或perl,或者(b)你不使用bash shell(即你使用zsh),那么shebang真的很重要但是你需要运行需要在bash中运行的东西. (2认同)
  • 错误:`execve(2)`系统调用不使用`$ SHELL`变量.它是解释shebang的核心. (2认同)

Bal*_*man 16

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


Nou*_*him 16

家当是一个指令加载器使用的是后指定的程序#!,当您尝试执行它解释为有问题的文件.所以,如果你尝试运行一个名为foo.sh其具有#!/bin/bash顶部,运行的实际命令/bin/bash foo.sh.这是为不同程序使用不同解释器的灵活方式.这是在系统级实现的,用户级API是shebang约定.

同样值得一提的是,shebang是一个神奇的数字 - 一个人类可读的数字,它将文件标识为给定解释器的脚本.

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


jay*_*ngh 14

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

Bash有经过多年的发展采取的代码kshsh.

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

#! 通常被称为"哈希砰","嘻嘻"或"沙梆".


Uda*_*ant 9

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