【发布时间】:2018-12-17 14:13:09
【问题描述】:
我被要求在 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);
}
如果不是tokExec 末尾的execvp,我将使用execv,如果我的输入只有ls 或ps 等execv 很好,但是如果我向输入,例如:ls -l myshell.c 或 evev 只是 ls -l 或 ps aux 我得到了 error 输出。
man 几乎没有提到这些功能之间的差异,但它声称:
execv()、execvp() 和 execvpe() 函数提供了一个指向以 null 结尾的字符串的指针数组,这些字符串表示新程序可用的参数列表。首先 按照惯例,参数应该指向与正在被调用的文件关联的文件名 执行。指针数组必须以空指针终止。
总之,在这种情况下修复我的程序的execv 和execvp 之间有什么区别?我知道execv 也适用于 bash 命令,因为如果我输入不带参数的 bash 命令,它就可以工作,并且这两个函数的签名是相同的。感谢您的帮助!
【问题讨论】:
-
你看
execv和errno的返回值了吗? -
进一步查看“execlp() 和 execvp() 的特殊语义”下的文档,其中解释了 execlp() 的作用,execve() 的作用。
-
execv返回int。我试过man errno,但我看不到任何返回值......无论如何与这个问题有什么关系? (让我好奇) -
perror给了我No such file or directory,答案中对此进行了解释,对于execv,您需要通过整个路径。 -
喜欢
/bin/ls?