2
你好,感謝你的關注。我正在嘗試實現我自己的shell。我有幾個關於我的代碼和關於任務解析的問題。下面我介紹我以前的代碼和問題:實施自己的外殼
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <ctype.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
void parse(char *line, char **argv, char **argv2)
{
while (*line != '\0')
{
while (*line == ' ' || *line == '\t' || *line == '\n')
{
*line++ = '\0';
}
if(*line == '>' && *(line+1) == '>')
{
while (*line != '\0' && *line != ' ' && *line != '\t' && *line != '\n')
{
line++;
}
while (*line == ' ' || *line == '\t' || *line == '\n')
{
*line++ = '\0';
}
*argv2 = line;
break;
}
if(*line == '&')
{
break;
}
*argv++ = line;
while (*line != '\0' && *line != ' ' && *line != '\t' && *line != '\n')
{
line++;
}
}
*argv = '\0';
}
void execute(char **argv, int option)
{
pid_t pid;
int status;
if ((pid = fork()) < 0)
{
printf("*** ERROR ***\n");
exit(1);
}
else if (pid == 0)
{
if (execvp(*argv, argv) < 0)
{
printf("*** ERROR ***\n");
exit(1);
}
}
else if(option == 1)
{
while (wait(&status) != pid);
}
}
void execute2(char *command, char **argv, char **argv2)
{
pid_t pid;
int status;
if ((pid = fork()) < 0)
{
printf("*** ERROR ***\n");
exit(1);
}
else if (pid == 0)
{
//close(1);
parse(command, argv, argv2);
int output = open(*argv2, O_APPEND | O_WRONLY);
dup2(output,1);
if (strcmp(argv[0], "exit") == 0)
exit(0);
if (execvp(*argv, argv) < 0)
{
printf("*** ERROR ***\n");
exit(1);
}
close(output);
}
else
{
while (wait(&status) != pid);
}
}
int specialChar(char *argv)
{
int i=0;
while(argv[i]!='\0')
{
if(argv[i]=='>' && argv[i+1]=='>')
return 1;
else if(argv[i]=='&')
return 2;
else if(argv[i]=='|')
return 3;
i++;
}
}
void main()
{
char command[20];
char *argv[64];
char *argv2[1];
char **history = (char**)malloc(20*sizeof(char*));
int counterHistory1=-1;
int counterHistory2=0;
int i;
for(counterHistory2 = 0; counterHistory2<20; counterHistory2++)
{
history[counterHistory2]=(char*)malloc(100*sizeof(char));
}
FILE *file;
file=fopen("history", "w");
if(!file)
printf("ERROR");
while (1)
{
printf("Shell -> ");
gets(command);
counterHistory1++;
strcpy(history[counterHistory1],command);
fopen("history", "w");
if(counterHistory1<20)
for(i=0; i<=counterHistory1; i++)
{
fprintf(file,"%s\n",history[i]);
}
else
for(i=counterHistory1-20; i<counterHistory1; i++)
{
fprintf(file,"%s\n",history[i]);
}
fflush(file);
printf("\n");
switch(specialChar(command))
{
case 1:
//close(1);
execute2(command,argv,argv2);
break;
case 2: //running program in background
parse(command, argv, argv2);
if (strcmp(argv[0], "exit") == 0)
exit(0);
execute(argv,0);
break;
case 3:
break;
default:
parse(command, argv, argv2);
if (strcmp(argv[0], "exit") == 0)
exit(0);
execute(argv,1);
break;
}
fclose(file);
}
}
1)當最後一個標誌從用戶剛開是「&」我需要在後臺運行我的程序。我已經讀過,如果我不打電話等待,我可以做到這一點。我做得很好還是應該改變一些東西?
2)如果我發現「>>」我應該重定向輸出到文件。例如,我得到ls >>輸出,所有的目錄和文件都應該寫入文件「輸出」。不幸的是,它只能使用一次。在此之後,我的程序停止。我認爲這個過程從來沒有完成,然後我不能寫下一個命令。我試圖殺死那個程序,但它沒有成功,或者我做錯了什麼。
3)在我的殼,我應該創建一個任意長度的管道|標誌。我不知道如何RESOLV這個問題......
感謝您的解答和幫助。
下點2)是改進 – ByQ
你的意思是你想寫解釋器本身?你能解釋一下「counterHistory1,2」,「歷史」是什麼? –
只是一些建議 - 如果你沒有打開歷史文件,你爲什麼不暗戀?爲什麼你使用最大長度爲20的命令?沒什麼! –