编写shell程序时的分段错误C
我的代码运行良好,直到我添加了额外的内容,比如识别和处理cd、>、>和|。你能检查一下我的代码,看看哪里出错了吗? 顺便说一句,任务的要求仅为1根管道。我认为这个问题是从for循环开始的,因为我把printf放在它的后面,检查它是否会打印args[k],它确实会打印,但是后来错误出现了,程序停止了编写shell程序时的分段错误C,c,shell,unix,C,Shell,Unix,我的代码运行良好,直到我添加了额外的内容,比如识别和处理cd、>、>和|。你能检查一下我的代码,看看哪里出错了吗? 顺便说一句,任务的要求仅为1根管道。我认为这个问题是从for循环开始的,因为我把printf放在它的后面,检查它是否会打印args[k],它确实会打印,但是后来错误出现了,程序停止了 #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/wai
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <string.h>
#include <fcntl.h>
int main()
{
const int MAX_ARGS = 10;
char *token[MAX_ARGS + 1]; /*assume max number of token <=10*/
char *temp;
char line[256], command[MAX_ARGS];
char prompt[] = "sh2 % ";
pid_t pid;
int i=0, j,k, status;
printf("%s", prompt);
while (fgets(line, sizeof line, stdin) != NULL)
{
line[strlen(line)-1] = '\0'; /*get rid of \n*/
token[0] = strtok(line," ");
strcpy(command,token[0]);
temp = strtok(NULL," ");
while (temp != NULL)
{
i = i+1;
token[i] = temp;
temp = strtok(NULL," ");
}
char *args[i+2];
for (j = 0; j < (i+1); j++)
{
args[j] = token[j];
}
args[i+1] = NULL;
if (!strcmp("exit",command))
exit(0);
if (!strcmp("cd", command))
{
int success;
if (success = chdir(args[1]) <0)
{
printf("Failed to change dir.\n");
}
}
else
{
int piping = 0;
int fd;
for (k = 0; k < sizeof args; k++)
{
if (!strcmp(">",args[k]))
{
fd = open(args[k+1],O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR | S_IXUSR);
if (fd <0) { printf("Open file failed.\n");}
else
{
dup2(fd, 1);
args[k] = '\0';
fflush(stdout);
close(fd);
}
}
if (!strcmp("<", args[k]))
{
fd = open(args[k+1], O_RDONLY);
if (fd <0) {printf("Open file failed.\n");}
else
{
dup2(fd, 0);
args[k] = '\0';
close(fd);
}
}
if (!strcmp(">>", args[k]))
{
fd = open(args[k+1], O_APPEND | O_CREAT, S_IRUSR | S_IWUSR | S_IXUSR);
if (fd <0) {printf("Open file failed");}
else
{
dup2(fd,1);
args[k] = '\0';
fflush(stdout);
close(fd);
}
}
if (!strcmp("|", args[k]))
{
piping = 1;
}
} /*end for*/
if (!(piping))
{
pid = fork();
if (pid <0) {}
else if (pid == 0)
{
if ( (status = execvp(command, args)) < 0 )
{
printf("Command not found\n");
}
}
else /*parent*/
{
wait(&status);
} /*end parent*/
}/*end if not pipe*/
else /*its pipe*/
{
int pfd[2];
pipe(pfd);
fd = fork();
if (fd < 0) {}
else if (fd ==0)
{
close(pfd[1]);
dup2(pfd[0],0);
close(pfd[0]);
execvp(args[2],args[2]);
}
else /*parent*/
{
close(pfd[0]);
dup2(pfd[1],1);
close(pfd[1]);
execvp(args[0],args[0]);
}
}/*end pipe*/
} /*end outter else*/
printf("%s", prompt);
}/*end while*/
return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
int main()
{
常量int MAX_ARGS=10;
char*token[MAX_ARGS+1];/*假设最大令牌数
或者,由于您将最后一个元素设置为NULL
,因此可以执行以下操作
for (char **arg = args; *arg; arg++)
还请注意,您使用k
进行迭代,直到数组结束,然后使用k+1
,这很可能会导致问题。调试器怎么说?此循环:for(k=0;k
绝对是错误的-args
是一个指针数组,但您正在以字节为单位迭代它的大小。使用-g-O0
编译您的程序,在gdb
中运行您的程序,并使用bt
命令打印回溯。这将告诉您什么是分段错误。键入时它指示了什么“回溯”?(假设这里是gdb,但我认为这最终不会有什么关系)。再次,在gdb
-这是一个调试器中运行该程序。它在UNIX中运行。它不是UNIX的替代品。这将帮助您找到问题,并阻止世界和他的狗对您的帖子进行降级。如果您找不到问题,结果也将帮助我们帮助您。此外,请正确缩进您的代码(提示:indent-nut-
将为您提供一些可以粘贴到堆栈溢出中的内容)@VictorN您真的应该听从人们的建议,敦促您使用gdb或其他东西。它有一点学习曲线,但可以帮助很大。
num = sizeof(args) / sizeof(*args);
for (k = 0; k < num; k++)
for (char **arg = args; *arg; arg++)