Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
execvp如何运行命令?_C_File_Unix - Fatal编程技术网

execvp如何运行命令?

execvp如何运行命令?,c,file,unix,C,File,Unix,我知道execvp可用于执行以下简单命令: char* arg[] = {"ls", "-l", NULL}; execvp(arg[0],arg); 我想知道当我运行execvp时这里发生了什么。在手册页中,它显示execvp将流程图像的图像替换为新图像。然而,这里我运行的是一个命令,而不是一个可执行文件 具体来说,假设有一个命令特别需要输入,例如cat。如果我有一个文本文件text.txt,其中包含cat所需的文件名,并且我将stdin重定向到该文件的文件流,那么execle(“cat”,

我知道
execvp
可用于执行以下简单命令:

char* arg[] = {"ls", "-l", NULL};
execvp(arg[0],arg);
我想知道当我运行
execvp
时这里发生了什么。在手册页中,它显示
execvp
将流程图像的图像替换为新图像。然而,这里我运行的是一个命令,而不是一个可执行文件

具体来说,假设有一个命令特别需要输入,例如cat。如果我有一个文本文件text.txt,其中包含cat所需的文件名,并且我将stdin重定向到该文件的文件流,那么
execle(“cat”,“cat”,NULL)
execvp(“cat”,arg)
(显然arg存储
“cat”
NULL
)导致控制台中的输出与
cat/filename
相同?我的直觉是我必须读取该文件,并可能解析它以将参数存储在arg中。不过我想确定一下

提前谢谢

“ls”不仅仅是一个命令,它实际上是一个程序(大多数命令都是)。当你像那样运行execvp时,它会破坏你的整个程序、内存、堆栈、堆等等。。。在概念上“清除”并将其交给“ls”,以便它可以将其用于自己的堆栈、堆等


简而言之,execvp将销毁您的程序,并用另一个程序替换它,在本例中为“ls”。

以下是在
execvp
调用中发生的情况:

  • 您的libc实现在
    路径中搜索要执行的文件(如果适用)。类UNIX系统中的大多数(如果不是全部的话)命令都是可执行的。如果不是,会发生什么?试试看。看一看
  • 通常,如果找到可执行文件,将调用
    execve
    execve
    的一部分可以在libc中实现,也可以是系统调用(如在Linux中)
  • Linux通过为程序分配内存、打开程序、安排程序执行来准备程序,初始化内存结构,设置从提供的参数到
    execvp
    调用的参数和环境,找到适合加载二进制文件的处理程序,并设置当前任务(调用方
    execvp
    )因为没有执行。您可以找到它的实现
  • 上述所有步骤均符合POSIX设定的要求,这些要求在相关章节中有所描述

    我的直觉是我必须读取该文件,并可能解析它以将参数存储在arg中。不过我想确定一下

    你的直觉基本上是正确的。作为示例使用的
    cat
    实用程序有两个单独的代码路径:

    • 如果有指定为参数的文件名,它将依次打开和读取每个文件名
    • 如果没有指定文件名,它将从标准输入读取

    此行为是在
    cat
    实用程序中具体实现的——它没有在任何较低级别上实现。特别是,它绝对不是
    exec
    系统调用的一部分。
    exec
    系统调用根本不“查看”参数;他们只需将它们直接传递到
    argv
    中的新流程,该流程将以其认为合适的方式处理它们。

    关于您的问题:

    在手册页中,它显示
    execvp
    替换流程图像的图像 用新的。但是在这里,我运行的是一个命令,而不是 可执行文件

    很久以前,shell非常有限,几乎所有UNIX命令都是独立的可执行文件。现在,为了提高速度,UNIX命令的一些子集是在shell本身内部实现的,这些命令称为
    内置命令
    。您可以通过
    type
    命令检查shell中内置或未内置的任何命令:

    λ ~/ type echo
    echo is a shell builtin
    
    (可在shell的
    man
    页面中找到带说明的完整内置项列表,例如
    man bash内置项
    man内置项

    但大多数命令仍有可执行的对应项:

    λ ~/ whereis echo
    /bin/echo
    
    因此,在您跑步的具体情况下:

    char* arg[] = {"ls", "-l", NULL};
    execvp(arg[0],arg);
    
    实际上,您正在将当前进程的地址空间替换为(很可能)
    /bin/ls


    我的直觉是我必须读取文件,并可能解析它来存储 arg中的参数

    你确实有。但您也可以使用一些内核内函数,即“shebang”:
    不要将文件名放在单独的文件中,而是将所谓的shebang添加为要cat的文件的第一行:

    #!/bin/cat
    
    并向其添加
    chmod+x
    。然后可以将其作为可执行文件运行(通过任何
    exec
    函数或shell):

    当然,它的缺点是使用文件打印
    shebang
    本身,但在kernel=)中这样做仍然很有趣

    顺便说一下,您描述的问题非常常见,以至于有一个名为
    xargs
    的特殊可执行文件(在非常简化的解释中)在通过stdin传递的参数列表上执行给定的程序。有关更多信息,请咨询
    man xargs


    为了便于记忆
    exec
    -系列,我经常使用下表:

               Figure 8.14. Differences among the six exec functions
    +----------+----------+----------+----------+--------+---------+--------+
    | Function | pathname | filename | agr list | argv[] | environ | envp[] |
    +----------+----------+----------+----------+--------+---------+--------+
    |  execl   |    *     |          |     *    |        |    *    |        |
    +----------+----------+----------+----------+--------+---------+--------+
    |  execlp  |          |    *     |     *    |        |    *    |        |
    +----------+----------+----------+----------+--------+---------+--------+
    |  execle  |    *     |          |     *    |        |         |   *    |
    +----------+----------+----------+----------+--------+---------+--------+
    |  execv   |    *     |          |          |    *   |    *    |        |
    +----------+----------+----------+----------+--------+---------+--------+
    |  execvp  |          |    *     |          |    *   |    *    |        |
    +----------+----------+----------+----------+--------+---------+--------+
    |  execve  |    *     |          |          |    *   |         |   *    |
    +----------+----------+----------+----------+--------+---------+--------+
    |  letter  |          |    p     |     l    |    v   |         |   e    |
    +----------+----------+----------+----------+--------+---------+--------+
    
    因此,在您的例子中,
    execvp
    接受filename、argv(v)和environ(e)。 然后,它尝试通过将
    filename
    (在您的例子中是
    cat
    )附加到
    path
    中的每个路径组件来“猜测”路径名(也称为完整路径),直到找到带有可执行文件名的路径

    更多关于
    exec
    引擎盖下发生的事情(包括继承内容)的信息可以在aka APUE2中找到。

    如果您对UNIX内部结构感兴趣,您可能应该阅读它。

    linux中的所有命令都是可执行的。在终端中键入
    哪个ls
    ,以查看
    ls
    程序的位置。实际上,当你说
    ls
    @Alex时,你正在运行一个可执行文件:除了一些在shell中实现的特殊命令,比如
    cd
    sourc
    
               Figure 8.14. Differences among the six exec functions
    +----------+----------+----------+----------+--------+---------+--------+
    | Function | pathname | filename | agr list | argv[] | environ | envp[] |
    +----------+----------+----------+----------+--------+---------+--------+
    |  execl   |    *     |          |     *    |        |    *    |        |
    +----------+----------+----------+----------+--------+---------+--------+
    |  execlp  |          |    *     |     *    |        |    *    |        |
    +----------+----------+----------+----------+--------+---------+--------+
    |  execle  |    *     |          |     *    |        |         |   *    |
    +----------+----------+----------+----------+--------+---------+--------+
    |  execv   |    *     |          |          |    *   |    *    |        |
    +----------+----------+----------+----------+--------+---------+--------+
    |  execvp  |          |    *     |          |    *   |    *    |        |
    +----------+----------+----------+----------+--------+---------+--------+
    |  execve  |    *     |          |          |    *   |         |   *    |
    +----------+----------+----------+----------+--------+---------+--------+
    |  letter  |          |    p     |     l    |    v   |         |   e    |
    +----------+----------+----------+----------+--------+---------+--------+