我正在尝试用 C 语言为 ubuntu 编写一个基本的 shell。我想在一行中执行多个命令,用分号分隔。我正在尝试运行它,但收到消息“段错误(核心已转储)”
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#ifdef _WIN32
#include <windows.h>
#define chdir _chdir
#else
#include <unistd.h>
#endif
#define MAX_LENGTH 512
int main(int argc, char *argv[]) {
char *cmd;
char line[MAX_LENGTH];
char *token[20];
int i=0;
int j=0;
int k=0;
char* args[20];
while (1) {
printf("8334>");
if (!fgets(line, MAX_LENGTH, stdin)) break;
while ((cmd = strtok(line, ";")) != NULL)
{
printf("<<%s>>\n", cmd);
strcpy(token[i], cmd);
i+=1;
cmd = NULL;
}
for(j=0;j<i;j++){
k=0;
while ((cmd = strtok(token[j], " ")) != NULL)
{
printf("<<%s>>\n", cmd);
strcpy(args[k],cmd);
k+=1;
cmd = NULL;
}
args[k]=NULL;
pid_t pid;
int status;
if ((pid = fork()) < 0) { /* fork a child process */
printf("*** ERROR: forking child process failed\n");
exit(1);
}
else if (pid == 0) { /* for the child process: */
if (execvp(args[0], args) < 0) { /* execute the command */
printf("*** ERROR: exec failed\n");
exit(1);
}
}
else { /* for the parent: */
while (wait(&status) != pid) /* wait for completion */
;
}
for(int l=0;l<20;l++)
args[l]=NULL;
}
}return 0;
}
最佳答案
我看到的主要问题是,您没有保留用于将字符串复制到 args[i]
和 token[i]
的空间;您正在为指针数组保留空间,但不为指针应指向的内容保留空间:
char *token[20]; // reserves place for 20 pointers
...
strcpy(token[i], cmd); // token[i] has not been initialized...
克服这个问题最简单的方法可能是编写
token[i] = strdup(cmd);
而不是strcpy
;请注意,strdup
自动保留足够的内存来保存副本,而 strcpy
则期望该空间之前已被保留。
无论如何,不要忘记释放不再使用的内存,也不要忘记对 args
执行此操作。
代码中还可能存在其他问题;例如,当使用 strtok
时,只有第一个调用会传递要分割的行,而所有连续调用都应传递 NULL
(参见 doku)。但我认为这就是您和您的调试器可以取得进展的级别:-)
关于c - 带有多个命令的 C Shell,段错误(核心转储),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41763793/