こんにちは、ありがとうございます。自分のシェルを実装しようとしています。私は自分のコードとタスクの解決についていくつかの質問があります。私は私の前のコードとの質問提示下:独自のシェルを実装する
#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)利用者からのgettin最後の記号は「&は、」私は、バックグラウンドで私のプログラムを実行する必要があります。私は待っていないとこれを行うことができると私は読んだ。私はこれをうまくやったのか、何か変えなければならないのか?
2)「>>」を見つけたら出力をファイルにリダイレクトする必要があります。たとえば、ls >>出力を取得すると、すべてのカタログとファイルをファイル "output"に書き込む必要があります。残念ながら、それは一度しか動作しません。その後、私のプログラムは停止されます。 procesは決して終わっていないと思うし、次のコマンドを書くことはできません。私はそのプロセスを殺そうとしましたが、うまくいかなかったか、何か間違ったことをしました。
3)私のシェルでは、任意の長さのパイプを|符号。私はその問題を解決する方法を知りません...
ありがとうございました。
サブポイント2へのアクセスを取得することにより、端末の制御を必要とする)であります改善しました – ByQ
あなたはインタプリタ自体を書いてほしいということですか? "counterHistory1,2,2"、 "歴史"について教えてください。 –
ちょっとした提案 - 履歴ファイルを開くことに失敗した場合、なぜあなたは挫折しないのですか?あなたはなぜ最大長20のコマンドを使用しますか?それは何もない! –