我正在尝试在C中编写一个简单的shell,它接受一个命令并使用子进程来执行该命令。例如,如果我输入:
ps -ael
我的子进程应该执行该命令及其参数。我打印出我的命令,因为它们存储在一个数组中。这就是我所看到的:
Array[0] = ps
Array[1] = -ael
Array[2] = NULL
当我执行时,我得到了这个:
error: unsupported SysV option
Usage:
ps [options]
Try 'ps --help <simple|list|output|threads|misc|all>'
or 'ps --help <s|l|o|t|m|a>'
for additional help text.
For more details see ps(1).
我的代码如下。
int main(void)
{
char *args[MAX_LINE/2 +1]; // command line arguments
char *cmdLine;
int should_run = 1; // flag to determine when to exit the program
int i, x;
printf("osh> ");
fflush(stdout);
fgets(cmdLine, MAX_LINE, stdin);
char *token = strtok(cmdLine, " ");
int position = 0;
while (token != NULL)
{
args[position++] = token;
token = strtok(NULL, " ");
}
i = 0;
while (args[i] != NULL)
{
printf("Array[%d] = %s\n", i, args[i]);
i++;
}
if (args[i] == NULL) printf("Array[%d] = NULL", i);
x = 0;
pid_t pid;
/* fork a child process*/
pid = fork();
if (pid < 0)
{
/*Error occured*/
fprintf(stderr, "Fork failed.");
return 1;
}
else if (pid == 0)
{
/*child process*/
execvp(args[0], args); //error here
}
else
{
/*Parent process*/
wait(NULL);
printf("\nChild complete\n");
}
}
答案 0 :(得分:2)
fgets()
返回的字符串包含换行符,但您并未将其从字符串中删除。因此,您要将args[1]
设置为"-ael\n"
,而\n
不是有效选项。
在strtok()
分隔符中添加换行符:
char *token = strtok(cmdLine, " \n");
int position = 0;
while (token != NULL)
{
args[position++] = token;
token = strtok(NULL, " \n");
}
然后它将不会包含在令牌中。
你应该能够在输出中看到这一点,我打赌它会打印出来:
Array[0] = ps
Array[1] = -ael
Array[2] = NULL
那里有一个空行。
顺便说一句,我不知道你在哪里设置了NULL
的最后一个参数。当while
返回strtok()
时NULL
循环停止,因此它永远不会将结果分配给args[position++]
。你需要添加:
args[position] = NULL;
循环后。
并且不需要if (args[i] == NULL)
- 在满足条件之前停止循环,因此它保证是真的。