Linux脚本中的#!/usr/bin/python -tt是什么意思?

20 投票
5 回答
17517 浏览
提问于 2025-04-17 11:19

我知道在.sh的bash脚本开头会有一行

#!/bin/bash

这行是指向命令解释器可执行文件的。

但是在看谷歌的Python课程时,我注意到他们用的是

#!/usr/bin/python -tt

在网上冲浪时,我还发现了这种写法:

#!/usr/local/bin/python

甚至还有

#!/usr/bin/env python

所以,我对Python还很陌生,而且我只是一个普通的Linux用户,我对这行“魔法”代码有几个问题:

  1. 首先,这行代码的正确形式是什么?为什么?
  2. 在#!/usr/bin/python -tt中,-tt这个选项是什么意思?
  3. 在Linux中,哪个程序会解析这一行?
  4. 这行代码对于任何脚本的语法是什么?
  5. 如果每个文件都有自己的扩展名,为什么这行代码如此重要?
  6. 还有,每台电脑上的解释器可能存放在不同的地方,这样脚本就可能无法运行,这该怎么办?

这让我很感兴趣。

这行代码是什么?为什么要写这行?怎么写这行?为什么要这样写?...

5 个回答

1
  1. #!/usr/bin/env python
  2. 关于不一致的制表符使用会出现错误
  3. 内核
  4. #!/解释器的路径或者是/usr/bin/env
  5. *nix系统根本不检查文件扩展名(除了某些桌面环境可能会这样做)
  6. 这就是为什么你应该使用#!/usr/bin/env的原因

更多信息请查看 维基百科

7

来自手册的内容:

-t 当源文件在缩进时混合使用制表符和空格,并且这种混合方式依赖于制表符在空格中的值时,会发出警告。如果这个选项被使用两次,就会发出错误。

  1. 这一行的正确形式就是你想要使用的形式。
  2. 读取这一行的解释器叫做 shebang。如果你写一个Python脚本,第一行是 "#!/usr/bin/python",然后用bash来调用它,那么实际上是/bin/sh解释器读取第一行,并启动正确的解释器。
  3. 这就是shebang。它的语法由字符序列#!组成,也就是井号和感叹号。
  4. 在Linux中,文件扩展名通常不是很重要。你可以有一个没有.py扩展名的Python脚本。

例如:

shadyabhi@archlinux ~ $ cat a 
print "Hello World" 
shadyabhi@archlinux ~ $ python2 a 
Hello World 
shadyabhi@archlinux ~ $

即使shebang只有在你想用$./script来启动脚本时才是必要的,因为在这种情况下你没有提到想要使用的解释器。

15

问题 #1) 这一行叫做“shebang”,没有一种通用的格式适用于所有情况。例如:

#!python
#!/usr/bin/python
#!/usr/local/bin/python
#!/usr/bin/python -t

这些都是有效的形式,但可能在所有系统上都不适用:

#!python 只有在你的系统中能找到 python 程序时才会有效。

#!/usr/bin/python 只有在 python 程序确实在 /usr/bin 这个位置时才有效。

#!/usr/local/bin/python 也仅在 python 在 /usr/local/bin 这个位置时有效。

问题 #2)

#!/usr/bin/python -tt 是把 -tt 这个选项传给 python,就像你在命令行输入:

$ python -t somescript.py

一样。你可以在 shebang 行中传递任意的命令行参数给解释器。

问题 #3)

这一行是由操作系统内核和你当前使用的命令行解释器来解析的。#! 后面的内容告诉操作系统应该启动哪个程序来“执行”脚本的其余部分。

问题 #4)

脚本的语法取决于你使用的编程语言。例如,一个 PHP 脚本必须是这样的格式:

#!/usr/bin/php
<?php
  ... php code here ...

而一个 #!/usr/bin/perl 的 Perl 脚本必须使用 Perl 的语法等等……如果你把 PHP 代码放在一个 Perl 的 shebang 下,Perl 就会因为语法错误而报错,因为 PHP 代码不是 Perl 代码。

问题 #5)

Shebang 是为 Unix 系统设计的,在这些系统中,文件扩展名并不是用来识别文件类型的。一个 .c 文件被理解为 C 语言的源代码文件,但这只是一个约定。你可以把一个 Bash 脚本放在一个 .c 文件里,设置为可执行,并且加上 #!/bin/bash 的 shebang,它就会作为 Bash 脚本执行。

通过文件扩展名来判断可执行文件类型更像是 Windows 系统的做法。

问题 #6)

这和问题 #1 说的内容有关——如果 shebang 声明解释器在某个与实际位置不同的路径下,这个脚本就无法执行,直到修正 shebang 或者移动解释器。Shebang 很方便,但并不是万无一失的。

幸运的是,现在大多数解释器都安装在相对标准的位置,所以在 /some/wonky/weird/path 这样的地方找到 Perl 是不太常见的,通常它会在 /usr/bin 下。

撰写回答