1.名称含义
在Unix中,shebang其实就是指“#!”,它取自#(SHArp)和!(bang)。
2.作用
它是很多脚本文件中第一行的前两个字符,用来告诉Unix系统要用shebang后面指定的解释器来解释该脚本。所以,在很多脚本中,第一行往往都是这么写的:#! /abs/path/to/interpreter
3.来源
根据wikipedia上的解释,shebang最初由Dennis Ritchie引入的,时间大概是在Version 7和Version 8之间。也正是因为shebang是以#开头,所以很多Unix上的脚本都是用#作为注释的开始。常见的有:#!/bin/sh#!/usr/bin/perl -w#!/bin/awk -f#!/usr/bin/env python#!/usr/bin/ruby
4.shebang的路径
shebang没有你想象得这么简单。首先,它后面的解释器路径一般来说必须是绝对路径。(当然了,有人也说像#!python这样的也能执行。)如果不是,可能就会出现类似的错误:bash: ./foo.py: python: bad interpreter: No such file or directory因为shell会直接用execve去执行这个文件,出错马上就退出。而execve会通过shebang辨认出这个一个脚本文件,然后尝试用后面的解释器去执行,但它并没有在PATH中寻找解释器,而是完全依靠你给出的路径。如果你不想指定绝对路径或者出于可移植的原因不好指定,那么你应该试试用env(1),就上面的python的shebang一样,它会帮你在PATH中搜索。python之所以更倾向于这个还有个原因,就是env一般固定在/usr/bin目录下,而python的安装位置就相对不那么固定。用env时你应该注意这么一个事实:传递给解释器的argv和你想象得并不一样。下面这个就是不对的:#!/usr/bin/env perl -wshell会提示:/usr/bin/env: perl -w: No such file or directory错误的根源就是perl -w被当成了整体传递给env。用下面的程序来看一下参数传递过程:/*test.c*/#include int main(int argc, char** argv) { int i;for (i=0; i<ARGC; i++)fprintf(stdout, “argv[%d]: \”%s\”\n”, i, argv[i]);return 0;}然后把编译出的test当作解释器:$ cat invoker.sh#!/home/wangcong/test -1 -2 -3结果如下:$ ./invoker.sh a b cargv[0]: “/home/wangcong/test”argv[1]: “-1 -2 -3″argv[2]: “./invoker.sh”argv[3]: “a”argv[4]: “b”argv[5]: “c”当然了,并不是所有的Unix都是这样,但最起码Linux上的bash和zsh上就是如此。所以,要编写可移植的脚本,你应该当心这一点!