当我在shell中执行文件时,会发生什么情况?

乔希

所以,我以为我对此有很好的了解,但是只是进行了一次测试(回应我不同意某人的谈话),发现我的理解是有缺陷的...

尽可能详细地说明我在Shell中执行文件时会发生什么情况?我的意思是,如果我键入以下内容:如果./somefile some arguments在外壳程序中键入内容,然后按return键(并且somefile存在于cwd中,并且我具有的读取和执行权限somefile),那么在幕后会发生什么?

以为答案是:

  1. Shell进行syscall exec,将路径传递给somefile
  2. 内核检查somefile并查看文件的幻数,以确定它是否是处理器可以处理的格式
  3. 如果幻数表示文件是处理器可以执行的格式,则
    1. 创建一个新流程(在流程表中有一个条目)
    2. somefile被读取/映射到内存。创建了一个堆栈,执行跳转到的代码的入口点somefile,并ARGV初始化为参数数组(a char**["some","arguments"]
  4. 如果幻数是shebang,exec()如上所述产生一个新进程,但是所使用的可执行文件是shebang引用的解释器(例如/bin/bash/bin/perl),somefile并传递给STDIN
  5. 如果文件没有有效的幻数,则将出现诸如“无效文件(不良幻数):Exec格式错误”之类的错误。

但是有人告诉我,如果文件是纯文本,那么Shell会尝试执行命令(就像我键入一样bash somefile)。我不相信这一点,但我只是尝试了一下,这是正确的。因此,我显然对这里实际发生的事情有一些误解,并且想了解其机制。

当我在shell中执行文件时,会发生什么情况?(尽可能多的细节是合理的...)

斯蒂芬·基特

关于Linux上“程序如何运行”的最终答案是LWN.net上的两篇文章,令人惊讶的是,程序如何运行以及程序如何运行:ELF二进制文件第一篇文章简要介绍了脚本。(严格来说,最终答案在源代码中,但是这些文章更易于阅读,并提供了源代码的链接。)

一个小小的实验表明,您几乎完全正确,并且包含shell的简单命令列表文件的执行需要由shell处理。所述的execve(2)手册页包含用于测试程序的源代码,的execve; 我们将用它来查看没有外壳的情况。首先,编写一个testscr1包含以下内容的测试脚本:

#!/bin/sh

pstree

另一个testscr2,仅包含

pstree

使它们都可执行,并验证它们是否都从外壳运行:

chmod u+x testscr[12]
./testscr1 | less
./testscr2 | less

现在,使用execve(假设您在当前目录中构建了它)再试一次

./execve ./testscr1
./execve ./testscr2

testscr1仍然运行,但testscr2产生

execve: Exec format error

这表明外壳的处理方式testscr2不同。尽管它不处理脚本本身,但仍然可以/bin/sh用来执行脚本这可以通过管道来验证testscr2less

./testscr2 | less -ppstree

在我的系统上,我得到

    |-gnome-terminal--+-4*[zsh]
    |                 |-zsh-+-less
    |                 |     `-sh---pstree

如您所见,有一个我正在使用的外壳程序zsh,它启动了less,还有另一个外壳程序shdash在我的系统上)简单地运行脚本,该脚本程序运行了pstreein中zshzexecvein处理Src/exec.c:shell用于execve(2)尝试运行命令,如果失败,它将读取文件以查看其是否具有shebang,并进行相应的处理(内核也将完成此操作),以及失败,它尝试使用来运行文件sh,只要它没有从文件中读取任何零字节即可:

        for (t0 = 0; t0 != ct; t0++)
            if (!execvebuf[t0])
                break;
        if (t0 == ct) {
            argv[-1] = "sh";
            winch_unblock();
            execve("/bin/sh", argv - 1, newenvp);
        }

bash具有相同的行为,execute_cmd.c并通过有用的注释实现(如taliezin所指出的):

执行一个简单的命令,希望该命令在磁盘文件中的某个位置定义。

  1. fork ()
  2. 连接管道
  3. 查找命令
  4. 进行重定向
  5. execve ()
  6. 如果execve失败,请查看文件是否设置了可执行模式。如果是这样,并且它不是目录,则将其内容作为Shell脚本执行。

POSIX定义一组功能,被称为exec(3)功能,它包裹execve(2)并提供此功能太; 有关详细信息,请参见muru的答案。在Linux上,至少这些功能是由C库而不是内核实现的。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

当我在shell中执行文件时,会发生什么情况?

来自分类Dev

当我使用Ctrl + c终止Python脚本时,内部会发生什么情况?

来自分类Dev

iOS:当我从其他类调用重写的方法时,会发生什么情况

来自分类Dev

当我使用Ctrl + c终止Python脚本时,内部会发生什么情况?

来自分类Dev

当我们在C中将数字转换为较小的数字时,会发生什么情况?

来自分类Dev

当我从RAM运行持久性存储实时USB时会发生什么情况?

来自分类Dev

当我离开INT_MAX以外时会发生什么情况?

来自分类Dev

当我将unpack()作为lua的函数参数调用时,会发生什么情况?

来自分类Dev

当我从RAM运行持久性存储实时USB时会发生什么情况?

来自分类Dev

当我们将jar提交给风暴集群时会发生什么情况?

来自分类Dev

当我在依赖jar的项目中进行更改时会发生什么情况?

来自分类Dev

当多次执行同一块时,块中的softSelf和StrongSelf会发生什么情况?

来自分类Dev

我执行apt-get升级时会发生什么情况?

来自分类Dev

如果应用程序处于睡眠状态时执行PerformSelector会发生什么情况?

来自分类Dev

如果我在Git中假定未更改的早期文件集上进行更改,会发生什么情况?

来自分类Dev

当我以“ wb”模式写入文件时,会发生什么?

来自分类Dev

当我从12.04LTS升级到14.04LTS时,如果失去了互联网连接,会发生什么情况?

来自分类Dev

如果在我的java文件中使用了很多@SuppressWarnings,会发生什么情况?

来自分类Dev

调用exec()时,线程会发生什么情况?

来自分类Dev

在提示中键入“ unset *”时,会发生什么情况?

来自分类Dev

在提示中键入“ unset *”时,会发生什么情况?

来自分类Dev

硬盘突然关闭时,磁头会发生什么情况?

来自分类Dev

当我在Amazon S3中将Quiet设置为true以便在deleteObjects()方法中启用安静模式时会发生什么情况?

来自分类Dev

如果我们在App Delegate中的didFinishLaunching中返回NO,会发生什么情况

来自分类Dev

当该地址中的内容换出并返回时,指针中存储的地址会发生什么情况?

来自分类Dev

如果我在Spark中两次缓存相同的RDD,会发生什么情况?

来自分类Dev

如果我在GCC中编译并链接到不需要的库,会发生什么情况?

来自分类Dev

如果我取消选中“软件和更新”中的所有PPA,会发生什么情况?

来自分类Dev

从C中main返回时正在运行的线程会发生什么情况?

Related 相关文章

  1. 1

    当我在shell中执行文件时,会发生什么情况?

  2. 2

    当我使用Ctrl + c终止Python脚本时,内部会发生什么情况?

  3. 3

    iOS:当我从其他类调用重写的方法时,会发生什么情况

  4. 4

    当我使用Ctrl + c终止Python脚本时,内部会发生什么情况?

  5. 5

    当我们在C中将数字转换为较小的数字时,会发生什么情况?

  6. 6

    当我从RAM运行持久性存储实时USB时会发生什么情况?

  7. 7

    当我离开INT_MAX以外时会发生什么情况?

  8. 8

    当我将unpack()作为lua的函数参数调用时,会发生什么情况?

  9. 9

    当我从RAM运行持久性存储实时USB时会发生什么情况?

  10. 10

    当我们将jar提交给风暴集群时会发生什么情况?

  11. 11

    当我在依赖jar的项目中进行更改时会发生什么情况?

  12. 12

    当多次执行同一块时,块中的softSelf和StrongSelf会发生什么情况?

  13. 13

    我执行apt-get升级时会发生什么情况?

  14. 14

    如果应用程序处于睡眠状态时执行PerformSelector会发生什么情况?

  15. 15

    如果我在Git中假定未更改的早期文件集上进行更改,会发生什么情况?

  16. 16

    当我以“ wb”模式写入文件时,会发生什么?

  17. 17

    当我从12.04LTS升级到14.04LTS时,如果失去了互联网连接,会发生什么情况?

  18. 18

    如果在我的java文件中使用了很多@SuppressWarnings,会发生什么情况?

  19. 19

    调用exec()时,线程会发生什么情况?

  20. 20

    在提示中键入“ unset *”时,会发生什么情况?

  21. 21

    在提示中键入“ unset *”时,会发生什么情况?

  22. 22

    硬盘突然关闭时,磁头会发生什么情况?

  23. 23

    当我在Amazon S3中将Quiet设置为true以便在deleteObjects()方法中启用安静模式时会发生什么情况?

  24. 24

    如果我们在App Delegate中的didFinishLaunching中返回NO,会发生什么情况

  25. 25

    当该地址中的内容换出并返回时,指针中存储的地址会发生什么情况?

  26. 26

    如果我在Spark中两次缓存相同的RDD,会发生什么情况?

  27. 27

    如果我在GCC中编译并链接到不需要的库,会发生什么情况?

  28. 28

    如果我取消选中“软件和更新”中的所有PPA,会发生什么情况?

  29. 29

    从C中main返回时正在运行的线程会发生什么情况?

热门标签

归档