构建一个基本的shell,更具体地使用execvp()
问题描述:
在我的程序中,我将用户输入并将其解析为2d char数组。该阵列声明为:构建一个基本的shell,更具体地使用execvp()
char parsedText[10][255] = {{""},{""},{""},{""},{""},
{""},{""},{""},{""},{""}};
我使用fgets来抓取用户输入并用sscanf解析它。这一切都按我的想法运作。
在此之后,我想将parsedText传递给execvp,parsedText [0]应该包含路径,如果提供了任何参数,那么它们应该在parsedText [1]通过parsedText [10]。
execvp(parsedText [0],parsedText [1])有什么问题?
有一点可能值得一提的是,如果我只提供一个没有任何参数的“ls”这样的命令,它似乎工作得很好。
这是我的代码:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "308shell.h"
int main(int argc, char *argv[])
{
char prompt[40] = "308sh";
char text[40] = "";
char parsedText[10][40] = {{""},{""},{""},{""},{""},
{""},{""},{""},{""},{""}};
// Check for arguments to change the prompt.
if(argc >= 3){
if(!(strcmp(argv[1], "-p"))){
strcpy(prompt, argv[2]);
}
}
strcat(prompt, "> ");
while(1){
// Display the prompt.
fputs(prompt, stdout);
fflush(stdout);
// Grab user input and parse it into parsedText.
mygetline(text, sizeof text);
parseInput(text, parsedText);
// Check if the user wants to exit.
if(!(strcmp(parsedText[0], "exit"))){
break;
}
execvp(parsedText[0], parsedText[1]);
printf("%s\n%s\n", parsedText[0], parsedText[1]);
}
return 0;
}
char *mygetline(char *line, int size)
{
if (fgets(line, size, stdin))
{
char *newline = strchr(line, '\n'); /* check for trailing '\n' */
if (newline)
{
*newline = '\0'; /* overwrite the '\n' with a terminating null */
}
}
return line;
}
char *parseInput(char *text, char parsedText[][40]){
char *ptr = text;
char field [ 40 ];
int n;
int count = 0;
while (*ptr != '\0') {
int items_read = sscanf(ptr, "%s%n", field, &n);
strcpy(parsedText[count++], field);
field[0]='\0';
if (items_read == 1)
ptr += n; /* advance the pointer by the number of characters read */
if (*ptr != ' ') {
strcpy(parsedText[count], field);
break; /* didn't find an expected delimiter, done? */
}
++ptr; /* skip the delimiter */
}
}
答
execvp
需要一个指针的指针(char **
),而不是一个指针数组。它应该是指向char *
指针数组的第一个元素的指针,由空指针终止。
编辑:这里有一个(不太好)的方式来作出适当的指针数组为execvp
:
char argbuf[10][256] = {{0}};
char *args[10] = { argbuf[0], argbuf[1], argbuf[2], /* ... */ };
当然在现实世界中你的争论很可能来自一个命令行字符串用户输入,并且它们之间可能至少有一个字符(例如空格),所以更好的方法是修改原始字符串,或者复制它,然后修改重复项,添加空终止符在每个参数之后并设置args[i]
指向字符串的右偏移量。
您可以在每个步骤中做很多动态分配(malloc
),但是您必须编写代码来处理每个可能的故障点。 :-)
我想我还是有点困惑(char **)。那么我会如何正确定义这些char数组? 此外,这是作业,所以我完全用一个简单的例子。不要试图把我的作业当作/。 – tgai 2011-02-05 22:25:45