【问题标题】:What does it mean in linux scripts? #!/usr/bin/python -tt在linux脚本中是什么意思? #!/usr/bin/python -tt
【发布时间】:2012-02-21 10:44:56
【问题描述】:

我知道 .sh bash 脚本的开头是

#!/bin/bash

它指向命令解释器可执行文件。

但在观看 Google Python Class http://www.youtube.com/watch?v=tKTZoB2Vjuk 时,我注意到他们使用 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. 那么,在每个计算机解释器中,某种脚本将存储在不同的地方而不是另一个地方呢?并且脚本无法运行。

这对我来说真的很有趣。 这是什么线?为什么是这条线?这行怎么写?为什么会这样?...

【问题讨论】:

    标签: python linux bash interpreter


    【解决方案1】:

    这被称为shebang。它告诉系统它应该将文件作为参数传递给指定的程序,而不是尝试执行它本身。

    首先,这条线的正确形式是什么?为什么?

    正确的路径是安装 Python 解释器的位置。参数 (-tt) 将取决于您想要什么。有些人坚持#!/usr/bin/env,以防口译员碰巧在别处。

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

    我不会使用python,所以必须由其他人来回答。

    当我在 Linux 中启动任何脚本(不完全是 Python 脚本)时,什么程序会解析并使用这一行?我认为这不是 bash,因为即使是 bash 脚本也需要这一行。

    我听说(并且很确定)它是内核。即使它是 bash,它也需要该行来告诉 bash 它应该是一个它应该解释而不是传递给另一个程序的脚本。 /usr/bin/env 是一个命令,它在 PATH 中搜索指定的参数,并将脚本传递给它找到的程序。

    对于任何脚本,该行的语法是什么?解析它的interpeter叫什么名字?

    语法与命令行相同,#!command arguments,但command 必须是绝对路径,PATH 不会被搜索。

    如果每个文件都有扩展名,为什么这一行如此必要?

    扩展在 *nix 中没有任何意义。我可以将 bash 脚本命名为 script.plscript.exe,甚至是 script,而无需扩展名。如果脚本有正确的 shebang 行,它将通过正确的解释器传递,否则内核尝试将其作为可执行文件执行并失败。系统不知道扩展。它们是用户的约定,仅此而已。

    那么,在每个计算机解释器中,某种脚本将存储在不同的地方而不是另一个地方呢?并且脚本无法运行。

    如果我理解正确,您是说不同的系统/发行版将解释器放在不同的位置(例如 /usr/bin/python/usr/local/bin/python),并询问系统如何知道使用哪个?
    答案是,它使用你给它的绝对路径。这实际上是可执行脚本的一个小问题,也是/usr/bin/env 流行的原因。正如我所说,envPATH 中搜索正确的解释器,所以只要你的系统有/usr/bin/env,你就设置好了,你不需要查找或保证解释器的位置。

    【讨论】:

      【解决方案2】:

      不同的路径是安装 python 解释器的位置。不同风格的 Linux 将其安装在不同的位置。

      Linux 不关心扩展,它是 Windows 的东西。

      bash 会话使用该行为您正在运行的脚本调用正确的解释器。

      文件存储、调用和使用的不同位置都是基于定义的文件应该在哪里以及由软件定位的位置。 Dev 用于设备,home 用于用户存储区域,bin 用于程序。但随着时间的推移,不同的系统需要不同的位置。

      我建议买一本关于 Linux/Unix 的书并学习文件系统的基础知识。它确实有很大帮助。

      【讨论】:

        【解决方案3】:

        来自手册页:

        -t 当源文件混合制表符和空格时发出警告 缩进取决于标签的价值 用空格表示。发出一个 两次给出选项时出错。

        1. 线的正确形式是您要使用的形式。
        2. 读取这一行的解释器称为shebang。如果您编写一个第一行为“#!/usr/bin/python”的 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 ~ $
        

        只有当你想使用 $./script 启动一个脚本时才需要 shebangs,因为在这种情况下你没有提到你想使用的解释器。

        【讨论】:

          【解决方案4】:

          问题 #1) 这条线被称为 shebang,并没有适用于通用的正确形式。例如

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

          都是有效/可接受的形式,但可能不适用于所有系统:

          #!python 仅当 python 可执行文件位于 shell 的 PATH 中某处时才有效

          #!/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
          

          在 shell 提示符下。您可以将任意命令行参数传递给 shebang 行上的解释器。

          问题 #3)

          该行由操作系统内核和您当前使用的 shell 解释。 #! 之后的内容只是告诉操作系统应该启动哪个程序来“执行”脚本的其余部分。

          问题 #4)

          脚本语法取决于您使用的语言。例如。 PHP shell 脚本的格式必须为

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

          #!/usr/bin/perl perl 脚本必须使用 Perl 语法等...如果您将 PHP 代码与 Perl shebang 放在一起,您只会让 Perl 用语法错误阻止脚本,因为 PHP 代码是 NOT perl 代码

          问题 #5)

          Shebangs 用于 Unix 系统,其中文件扩展名从未真正用于向操作系统识别文件类型。 .c 文件被理解为 C 语言源代码文件,但这只是一种约定。您可以将 Bash shell 脚本放入 .c 文件中,使其可执行,然后使用 #!/bin/bash shebang,它将作为 Bash 脚本执行。

          通过文件扩展名确定可执行类型更像是 Windows 的事情。

          问题 #6)

          这可以追溯到问题 #1 - 如果 shebang 声称解释器位于其他路径而不是它所在的位置,则在修复 shebang 或移动解释器之前,无法执行此特定脚本。 Shebangs 非常方便,但并非万无一失。

          谢天谢地,现在大多数解释器都安装在相当标准的位置,所以找到(比如说)Perl 安装在/some/wonky/weird/path 而不是/usr/bin 有点不寻常

          【讨论】:

          • 您在第 1 点列表中跳过了 #!/usr/bin/env python 替代项。某些特殊原因?
          • 哎呀,错过了那个。 env 是一个打印 otu 当前环境变量/值的 unix 应用程序。在大多数 shell 上,您可以执行 SOMEVAR=value name_of_app 来定义应该存在于该应用程序环境中的 env var(s)。做/usr/bin/env python 只是强制所有当前环境变量出现在python 中。
          • 查看 shadyabhi 对“-tt”的回答。
          【解决方案5】:
          1. #!/usr/bin/env python
          2. 关于标签使用不一致的问题
          3. 内核
          4. #!/path_to_the_interpreter 或 /usr/bin/env
          5. *nix 根本不检查扩展(除了某些 DE 可以这样做)
          6. 这就是为什么你应该使用 #!/usr/bin/env

          更多信息wiki

          【讨论】:

          • #!/usr/bin/env python 不允许您将 -tt 选项(或任何其他选项)传递给 python 解释器。另见this questionthis answer
          • @KeithThompson 这实际上是不正确的:使用 #!/usr/bin/env python -tt 工作并且完全按照要求执行:运行 python 解释器,首先在 PATH 中找到 -tt 选项,然后是有问题的脚本。
          • @JonathanCallen:不在我的系统上(Ubuntu 11.04);我得到/usr/bin/env: python -tt: No such file or directory。在 Solaris 9 上,它确实使用 python 调用脚本,但它似乎忽略了 -tt。你用的是什么系统?
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-06-25
          • 1970-01-01
          • 2013-02-10
          • 2011-11-14
          • 2012-04-19
          • 1970-01-01
          • 2010-11-13
          相关资源
          最近更新 更多