c - 理解为什么`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);
}
如果我将使用, 而不是execvp
最后的, 如果我的输入只是or etc很好,但是如果我在输入中添加参数,例如:或者 evev just或者我得到了一个输出。tokExec
execv
ls
ps
execv
ls -l myshell.c
ls -l
ps aux
error
几乎没有提到这些功能之间的man
差异,但它声称:
execv()、execvp() 和 execvpe() 函数提供了一个指向以 null 结尾的字符串的指针数组,这些字符串表示新程序可用的参数列表。按照惯例,第一个参数应该指向与正在执行的文件关联的文件名。指针数组必须以空指针终止。
总之,在这种情况下,execv
与execvp
修复我的程序有什么区别?我知道这execv
也适用于 bash 命令,因为如果我输入不带参数的 bash 命令,它就可以工作,并且这两个函数的签名是相同的。谢谢你的帮助!
解决方案
答案在手册页中。如果您在引用的部分之后阅读该部分,它会谈到差异
如果指定的文件名不包含斜杠 (/) 字符,则 execlp()、execvp() 和 execvpe() 函数会复制 shell 在搜索可执行文件时的操作。在 PATH 环境变量中指定的以冒号分隔的目录路径名列表中查找该文件。如果未定义此变量,则路径列表默认为当前目录,后跟 confstr(_CS_PATH) 返回的目录列表。(此 confstr(3) 调用通常返回值“/bin:/usr/bin”。)
推荐阅读
- c# - 带有表达式的 EF LINQ 查询:预期方法名称 - 如何将表达式传递给函数以在 EF 查询中使用?
- reactjs - 如何仅在 ReactJS 中的组件上使用 reactstrap?
- c++ - 未调用 mosquitto c API 的回调函数
- lisp - 在 Common Lisp 的 Progn 中加载包
- c++ - 打开不存在的文件时如何使ofstream构造函数失败?
- javascript - 控制台中的递归“扩展上下文无效”错误
- python - 使用 pd.to_datetime 将“对象”列转换为 %HH:MM:SS
- python-3.x - 在底图python中绘制点
- javascript - Firebase Cloud FireStore:插入大型数组
- python - 使用 lower 函数将 pyspark 数据框中单列中的值转换为文本清理中的小写