【问题标题】:What is used by bash to open/execute argv[0]?bash 使用什么来打开/执行 argv[0]?
【发布时间】:2015-02-07 20:02:08
【问题描述】:

如果这是一个愚蠢的问题,我提前道歉,但是我越深入研究它就越感到困惑。我正在自学 C,最近一直在研究文件“打开”相关的函数和宏,以便更好地了解到底发生了什么。

所以,我的愚蠢问题是,在运行 Centos 6.6 并使用 Bash shell 的系统上,当从命令提示符调用程序时,究竟是什么打开了 argv[0] 以执行?

我已经尝试过(我相信被称为)拦截程序并通过 LD_PRELOAD 指令导出共享对象文件,并且可以跟踪至少一些对“open”和“open64”的调用。

我使用的调试样式打印语句为我提供了正在打开的文件名,但是我注意到从命令行调用的程序(我假设为 argv[0])看起来不像被引用这些中的任何一个。

这导致我开始苦苦研究 bash 源代码,但没有取得任何实际进展。

我非常感谢任何关于我可能需要寻找什么以及在哪里寻找的指示?我在 argv、argv(、main(、execev、ioctl 和 fcntl 上进行了 grep'ed,谷歌搜索并搜索了留言板,但没有取得进展。

我将非常感谢任何关于此的建议或指示。

【问题讨论】:

  • exec* 系列函数是您想要跟踪的。执行文件和打开文件是完全不同的两件事。
  • shell fork 一个新进程和exec 文件,所以它根本不涉及open
  • exec*() 系列函数负责读取指定为第一个参数的文件。您不会看到单独的用户级打开操作;它由内核在内部处理。
  • 这个问题真的没有意义; shell以任何有意义的方式执行argv[0]。被调用的命令的路径是 execv 系列函数的一个独立参数,来自其参数向量。

标签: c linux bash shell


【解决方案1】:

获取bash 的源代码(注意:它不是一个简单的外壳——它是一个非常复杂的程序):

  • git clone git://git.savannah.gnu.org/bash.git

查看文件execute_cmd.c 和函数execute_disk_command()shell_execve()

基本上execute_disk_command() 执行fork()(通过辅助函数make_child() 后跟execve()(通过shell_execve())。

【讨论】:

【解决方案2】:

最终,execve() 是所有程序调用的入口点(在 POSIX 兼容的平台上)。它指示操作系统运行加载程序,该加载程序为执行新程序做好准备,并最终使其进入运行状态(并将其留给自己)。提供给 execve() 的一个参数是一个字符串——一个指向磁盘上可执行文件的文件系统路径。按照惯例,argv[0] 设置为相应的 basename*。参数被放置在新生成的程序的堆栈中,以便它可以访问它们。

http://linux.die.net/man/2/execve:

int execve(const char *filename, char *const argv[], char *const 环境 []);

execve() 执行 filename 指向的程序。文件名必须是 二进制可执行文件或以一行开头的脚本 形式:

#! interpreter [optional-arg]

argv 是传递给新程序的参数字符串数组。经过 convention,这些字符串中的第一个应该包含文件名 与正在执行的文件相关联。

【讨论】:

  • 可执行文件的路径和 argv[0] 不是必然相同的东西。这是传统的,但可以运行文件 A 并告诉它它的 argv[0] 是 B。
  • 当然,我应该澄清一下。将更新答案。
  • 经过编辑——特别是手册页引用——现在这是权威的;太棒了。
猜你喜欢
  • 2011-01-22
  • 1970-01-01
  • 1970-01-01
  • 2011-03-22
  • 1970-01-01
  • 1970-01-01
  • 2020-07-02
  • 2023-03-13
  • 2019-04-10
相关资源
最近更新 更多