脚本前的#!是什么作用?

shebang是什么?

在计算机领域中,Shebang(也称为Hashbang)是由井号和感叹号构成的字符序列:

1
#!

文件中存在shebang 的情况下,系统会分析shebang后的内容,并调用指定的解释器来解释执行文件的内容。

这个不用说想必大家也见过很多次了。

至于为什么叫这个名字,这里摘抄维基百科的解释:

Shebang的名字来自于SHArp和bang,或haSH bang的缩写,指代Shebang中#!两个符号的典型Unix名称。 Unix术语中,井号通常称为sharp,hash或mesh;而叹号则常常称为bang。也有看法认为,shebang名字中的sh来自于默认shell————Bourne shell的名称,sh,因为常常使用shebang调用之。

作用是什么

作用大家应该也都知道了,指定解释程序,这一点在《为什么执行自己的程序时需要加上点./》中也有更多解释,建议你参考阅读。

这里再举个小例子说明一下,假设文件test.txt内容为:

1
2
#!/bin/cat
hello 编程珠玑

在linux下执行:

1
2
3
$ ./test.txt
#!/bin/cat
hello 编程珠玑

其实等价于:

1
/bin/cat test.txt

所以不是说你的文件后缀是sh就是shell脚本,是py就是python脚本,linux下压根不认它们,这些扩展名只是给人看的,而不是给机器看的。
它们只认shebang,不认识的时候会被默认当成shell脚本。举例,下面的python代码如果没有加shebang:

1
print('hello world')

普通执行:

1
2
3
$ ./test.txt
./test.txt: line 1: syntax error near unexpected token `'hello world''
./test.txt: line 1: `print('hello world')'

看,被当成普通shell脚本了。

该怎么写?

shebang的写法很多,包括但不限于:

1
2
3
4
#!/usr/bin/env bash
#!/bin/bash
#!/bin/sh
#!/bin/sh -

上面这些写法通常都不会影响脚本的运行,但是它们有什么区别?推荐哪种写法呢?

从上面的写法中可以看到,都指定了bash或者sh的路径,但是不同的系统中,它们的路径可能不一样,而为了移植性考虑,建议选择第一种写法,它使用的是环境变量中配置的bash路径,而不是像其他写法那样,属于写死的路径。

这一点用于Python或者其他脚本语言也是成立的:

1
2
#!/usr/bin/env python3
print("hello 公众号编程珠玑")

总结

对于脚本类程序,shebang是必要的,因为它告诉系统应该如何来解释运行程序,当然你也可以运行时指定,但总归不是万全之策。至于写没有完全的对错之分。

关于本文的扩展内容,建议阅读《为什么执行自己的程序时需要加上点./》。

你通常都是怎么写的?欢迎留言。

守望 wechat
关注公众号[编程珠玑]获取更多原创技术文章
出入相友,守望相助!