unix exec族函数 关于参数的疑惑

问题不出在这几个函数,而在于看后文解释器的时候发现一个很奇妙的问题。 

#include <unistd.h>

int execl(const char *pathname, const char *arg0,
... /* (char *)0 */ );

int execv(const char *pathname, char *const argv []);

int execle(const char *pathname, const char *arg0, ...
           /* (char *)0,  char *const envp[] */ );

int execve(const char *pathname, char *const
 argv[], char *const envp []);

int execlp(const char *filename, const char *arg0,
 ... /* (char *)0 */ );

int execvp(const char *filename, char *const argv []);

 第一参数是路径名或者文件名, 后续的是一连串字符串参数或者指针数组。来研究一下文中的小程序。

#include "apue.h"
#include <sys/wait.h>

char    *env_init[] = { "USER=unknown", "PATH=/tmp", NULL };

int
main(void)
{
    pid_t   pid;

    if ((pid = fork()) < 0) {
        err_sys("fork error");
    } else if (pid == 0) {  /* specify pathname, specify environment */
        if (execle("/home/sar/bin/echoall", "echoall", "myarg1",
                "MY ARG2", (char *)0, env_init) < 0)
            err_sys("execle error");
    }

    if (waitpid(pid, NULL, 0) < 0)
        err_sys("wait error");

    if ((pid = fork()) < 0) {
        err_sys("fork error");
    } else if (pid == 0) {  /* specify filename, inherit environment */
        if (execlp("echoall", "echoall", "only 1 arg", (char *)0) < 0)
            err_sys("execlp error");
    }

    exit(0);
}
#include "apue.h"

int
main(int argc, char *argv[])
{
    int         i;
    char        **ptr;
    extern char **environ;

    for (i = 0; i < argc; i++)      /* echo all command-line args */
        printf("argv[%d]: %s\n", i, argv[i]);

    for (ptr = environ; *ptr != 0; ptr++)   /* and all env strings */
        printf("%s\n", *ptr);

    exit(0);
}

 对于:

execle("/home/sar/bin/echoall", "echoall", "myarg1",
                "MY ARG2", (char *)0, env_init)的调用,感性的判断认为,应该是将 echoall myarg1 MY ARG2三个参数传给 echoall 那么,加上函数本身,应该是有四个参数,然而结果却不是如此。输出的结果是:
  argv[0]: echoall
  argv[1]: myarg1
  argv[2]: MY ARG2为何argv[0]会变成了传入的第二个参数呢。百度很多说得都不是很明白。中文版,习惯了联系上下文阅读而不仔细查看字眼,翻看英文版看到仔细的阅读了一下。

Note also that we set the first argument, argv[0] in the new program, to be the filename component of the pathname. Some shells set this argument to be the complete pathname. This is a convention only. We can set argv[0] to any string we like.

exec参数的第一个参数是路径,将第二个参数设置为新程序的argv[0],这是第一参数,路径名的分量。某些shell把这个参数设置为完整的路径,只是为了方便。我们可以设置argv[0],第二个参数为任意值。

可是,这是为什么呢。
时间: 2024-10-11 07:12:49

unix exec族函数 关于参数的疑惑的相关文章

Linux学习笔记(8)-exec族函数

昨天学习了Linux下的进程创建,创建一个进程的方法极为简单,只需要调用fork函数就可以创建出一个进程,但是-- 介绍fork()函数的时候提到,在创建进程后,子进程与父进程有相同的代码空间,执行的是和父进程完全一样的代码-- 那这样的话,我辛辛苦苦创建一个进程,还有什么意义? 辛辛苦苦的养大了一个儿子,难道就是为了让他走老子的老路? 带着满心的疑惑,我又进行了下一章的学习,突然恍然大悟,原来还有一个叫exec族函数的东西,专门就是用来给新创建的进程分配工作的. 调用exec族函数并不创建进程

进程控制(十)---exec族函数

当使用fork()创建了一个子进程后,通常接着会使用 exec 族函数指定新的程序来覆盖子进程的代码段.数据段.堆和栈.从而让子进程去执行一个新的程序,而不是执行父进程的副本. ===================================================== exec 族函数中总共有 6 个函数: 上面 5 个函数属于库函数,这些函数都最终调用了下面的 execve 函数,这6个函数中,只有execve 函数属于Linux的系统调用. 出错返回: 这些函数在调用成功时不

嵌入式 Linux进程间通信(二)——exec族函数

嵌入式 Linux进程间通信(二)--exec族函数 exec函数族的作用是根据指定的文件名找到可执行文件,并用它来取代调用进程的内容,换句话说,就是在调用进程内部执行一个可执行文件.这里的可执行文件既可以是二进制文件,也可以是任何Linux下可执行的脚本文件. exec族函数包含如下函数: #include <unistd.h> extern char **environ; int execl(const char *path, const char *arg, ...); int exec

【Linux 进程】exec族函数详解

exec族的组成: 在Linux中,并不存在一个exec()的函数形式,exec指的是一组函数,一共有6个,分别是: #include <unistd.h> extern char **environ; int execl(const char *path, const char *arg, ...); int execlp(const char *file, const char *arg, ...); int execle(const char *path, const char *arg

exec系列函数(execl,execlp,execle,execv,execvp)使用

本节目标: exec替换进程映像 exec关联函数组(execl.execlp.execle.execv.execvp) 一,exec替换进程映像 在进程的创建上Unix采用了一个独特的方法,它将进程创建与加载一个新进程映象分离.这样的好处是有更多的余地对两种操作进行管理. 当我们创建了一个进程之后,通常将子进程替换成新的进程映象,这可以用exec系列的函数来进行.当然,exec系列的函数也可以将当前进程替换掉. 例如:在shell命令行执行ps命令,实际上是shell进程调用fork复制一个新

python之os.exec*族用法简结

os.exec*族主要用来代替当前进程,执行新的程序,不返回值.在UNIX上,新的执行程序加载到当前进程,与调用它的进程有相同的id. os.execl(path, arg0, arg1, ...) os.execle(path, arg0, arg1, ..., env) os.execlp(file, arg0, arg1, ...) os.execlpe(file, arg0, arg1, ..., env)o s.execv(path, args) os.execve(path, arg

函数的参数

定义默认参数要牢记一点:默认参数必须指向不变对象! 默认参数 由于我们经常计算x2,所以,完全可以把第二个参数n的默认值设定为2: def power(x, n=2): s = 1 while n > 0: n = n - 1 s = s * x return s 这样,当我们调用power(5)时,相当于调用power(5, 2): >>> power(5) 25 >>> power(5, 2) 25 而对于n > 2的其他情况,就必须明确地传入n,比如p

[Java]_函数传参的疑惑与思考

问题来源于leetcode上的两道题 Path Sum I && II,分别写了两个dfs. 1 void dfs(TreeNode node , int sum , ArrayList<Integer> curPath) 2 void dfs(TreeNode node , int sum , boolean ifExist) 问题:在1号中我可以在方法中修改curPath,在结束函数调用时,变量修改仍然生效.   在2号问题中,我即使在函数中修改了ifExist,结束函数调

python之函数的参数

定义函数的时候,我们把参数的名字和位置确定下来,函数的接口定义就完成了.对于函数的调用者来说,只需要知道如何传递正确的参数,以及函数将返回什么样的值就够了,函数内部的复杂逻辑被封装起来,调用者无需了解. Python的函数定义非常简单,但灵活度却非常大.除了正常定义的必选参数外,还可以使用默认参数.可变参数和关键字参数,使得函数定义出来的接口,不但能处理复杂的参数,还可以简化调用者的代码. 位置参数 我们先写一个计算x2的函数: def power(x): return x * x 对于powe