【发布时间】:2018-08-16 06:02:29
【问题描述】:
我正在尝试用 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");
}
}
【问题讨论】:
-
@Barmar Ubuntu 16.04
-
用
strace -f -eexecve your-prog运行它,看看它到底发生了什么。并检查是否包含隐藏空格(例如 printArray.. . = '%s') -
fgets()函数输入所有内容,包括“\n”(或缓冲区几乎已满),然后附加一个 NUL 字节。发布的代码需要将 '\n' 替换为 NUL 字节。否则,“\n”是放在args[]中的参数的一部分,这就是出现错误消息的原因。 -
关于:
fgets(cmdLine, MAX_LINE, stdin);和char *cmdLine;fgets()函数的第一个参数预计是指向数组/缓冲区的指针,以接收读取的数据。cmdLine被声明为“未初始化的指针”。 IE。该指针包含堆栈中cmdLine位置上的垃圾。这会导致未定义的行为,并可能导致段错误事件。建议:char cmdLine[ MAX_LINE ]; -
贴出的代码无法编译!除其他外,它缺少所需的
#include语句并且缺少MAX_LINE的定义您是否希望我们了解您的想法,包括哪个头文件以及您为MAX_LINE定义了什么值?