gpt4 book ai didi

c - 在终端上键入`node`时运行的代码

转载 作者:太空宇宙 更新时间:2023-11-04 00:20:07 25 4
gpt4 key购买 nike

我试图了解shebang是如何工作的,并想知道当您在终端提示符下键入node时会发生什么想知道它是否在某个地方调用了main我只了解基本知识,已经使用node一段时间了shebang以某种方式读取节点可执行文件,我不确定它在什么地方,以及从什么开始然后是实际计算表达式#!/usr/bin/env node并将其定向到shebang的代码,但这可能太复杂了,无法询问。

最佳答案

准确地说,“shebang”只是两个字符当Unix系统上的文件作为可执行文件(最终通过系统调用#!)调用时,内核会查看它的前几个字节,以确定它是哪种可执行文件如果这些字节将其标识为包含机器代码,那么内核将把机器代码加载到内存中,并使CPU开始执行它。如果机器代码是从C程序编译的,那么它的execve函数最终将被调用。(如果您想知道这个过程是如何工作的,请阅读John Levine的《Linkers and Loaders》一书。)
但是如果前两个字节是main#(ASCII值35和33),那么内核将扫描文件的第一行以查找解释器的名称,然后运行解释器,将!程序的名称作为命令行参数提供。(请参见this answer了解内核如何解析第一行的确切细节。)

./foo.js a b c d

而foo.js以 #!开头,那么内核的行为就好像用参数向量调用了 #! /usr/bin/node
/usr/bin/node ./foo.js a b c d

它将打开文件 execve,发现这是一个机器代码可执行文件,然后继续加载机器代码(节点解释器)并运行它然后Node的 /usr/bin/node函数会注意到它的第一个参数是 main,它将打开该文件并作为Javascript程序执行,而不是进入其交互式read evaluate打印循环。
节点解释器本身忽略 ./foo.js行,但它必须在其解释器中包含代码才能忽略它;内核不会过滤掉它在Unix上常用的许多解释语言(sh、awk、perl、python、ruby,…)中,注释从a #!一直运行到行尾,因此这是自动发生的;事实上,早在那天就选择了 #符号,因为sh注释从 #!一直运行到行尾Javascript注释不是这样工作的,因此Node必须在文件开头有一个特殊的 #大小写。
您显示的 #!行有一个额外的间接级别: #!使内核使用参数向量运行程序
/usr/bin/env node ./foo.js a b c d

#! /usr/bin/env node然后看到它的第一个参数是 /usr/bin/env,它沿着搜索路径查找名为 env的程序的可执行文件。搜索路径由环境变量定义:type
echo $PATH

在你的提示下学习它是什么。这是一个用冒号分隔的目录列表例如,PATH的公共值是
/usr/local/bin:/usr/bin:/bin

这意味着按顺序在目录 nodenode/usr/local/bin中查找程序;换句话说,使用PATH的值和上面的参数, /usr/bin将首先尝试运行
/usr/local/bin/node ./foo.js a b c d

如果这不起作用,它会尝试 /bin等等如果您不知道节点解释器(或其他什么)安装在哪里,则需要额外的间接寻址,因为内核的 env处理只接受 /usr/bin/node之后的绝对路径名;它不会为您执行路径搜索。如果您确实知道 #!安装在哪里,最好直接编写该路径名,这样您的程序的行为就不取决于调用用户的路径是什么(例如 some Linux distributions used to use the name #! for a completely unrelated program,因此,如果您有 node并且用户在其路径上的 /usr/bin/node之前没有 #! /usr/bin/env node,则会引起欢闹)。
我为 /opt/node-1.9/bin和以 /usr/bin开头的文件描述的行为不是 specified by POSIX(在该页中提到,但仅在非规范性基本原理部分中提到)。但是,它在您现在可能遇到的所有类Unix操作系统中是一致的。我不知道它到底有多大。

关于c - 在终端上键入`node`时运行的代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51602401/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com