了解为什么execvp在execv失败的地方工作

时间:2018-12-17 14:13:09

标签: c exec execvp execv

我被要求在C语言中实现一个“迷你外壳”。我决定使用execv,但它不起作用,当我将其更改为execvp时,它就可以工作了!看一下代码(该操作在tokExec函数中)

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>


void tokExec(char command[128])
{
    // 'strtok' may look innocent, but it modifies the string, so I want a copy of the original command.
    char tokString[128];
    // 'strlen' is the lenghth without the null terminator.
    strncpy(tokString,command,strlen(command)+1);


    char* tokPtr = NULL;
    char tok[] = " ";
    int narg = 0;
    tokPtr = strtok(tokString,tok);
    char *myargs[64];

    while(tokPtr != NULL)
    {
            printf("arg %d is: %s\n",narg,tokPtr);
            myargs[narg] = tokPtr;
            narg = narg + 1;
            tokPtr = strtok(NULL,tok);
    }
    printf("Total number of arguments: %d\n",narg);

    // add the final 'NULL' element.
    myargs[narg] = NULL;

    execvp(myargs[0],myargs);
    printf("error\n");
    exit(1);
}

void normal()
{
    char command[128];
    strcpy(command,"default\0");
    printf("myShellZ > ");
    gets(command);
    while(strcmp(command,"exit") != 0)
    {
            int status;
            pid_t pid;
            if( (pid = fork()) == 0 )
            {
                    tokExec(command);
            }
            wait(&status);
            printf("myShellz > ");
            gets(command);
    }
}

void debug()
{
    // TO DO ....
    int a = 3;
}

// switching between shell modes: normal or debug.
int main(int argc, char* argv[])
{
    if(argc == 1)
            normal();
    else if(strcmp("-debug",argv[1]))
            debug();
    else
            exit(1);

    exit(0);
}

如果我的输入仅为execvptokExec等{{1},而不是execv末尾的ls,我将使用ps }}很好,但是如果我在输入中添加参数,例如:execv或evev仅ls -l myshell.cls -l,我将得到ps aux的输出。

error几乎没有提到这些功能之间的区别,但它声称:

  

execv(),execvp()和execvpe()函数提供了一个指向以空值结尾的字符串的指针的数组,这些字符串表示新程序可用的参数列表。首先          按照惯例,参数应指向与该文件关联的文件名    被执行。指针数组必须以空指针终止。

总而言之,在这种情况下,固定程序的manexecv有什么区别?我知道execvp也适用于bash命令,因为如果我输入不带参数的bash命令,它将起作用,并且这两个函数的签名相同。感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

答案在手册页中。如果您在引用的部分之后阅读本节,则说明了区别

  

execlp(),execvp()和execvpe()函数复制动作   的          如果指定的文件名不存在,则在shell中搜索可执行文件          包含斜杠(/)字符。在冒号中查找文件          PATH环境变量中指定的目录路径名列表。如果          未定义此变量,路径列表默认为当前目录          然后是confstr(_CS_PATH)返回的目录列表。 (这个          confstr(3)调用通常返回值“ / bin:/ usr / bin”。)