我正在写一个简单的shell。我需要在这个shell上添加一个历史记录功能,这将允许我检查我的shell收到的先前命令。 我已经尝试了这么久,我无法弄清楚为什么我的command []数组在这里是NULL
for (command[numargs] = strtok_r(buf," ",&inner_ptr);
command[numargs];
command[numargs] = strtok_r(NULL," ",&inner_ptr))
++numargs;
printf("%s \n",command[numargs]);
printf(“%d \ n”,numargs); 如果(numargs) 执行(安培;命令[numargs]);
这意味着我的shell总是执行NULL
// shell代码。 Boojum,感谢您修复代码,错误是打印两个“? - >”
//壳牌
#include <unistd.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <iostream>
#include <signal.h>
#include <string.h>
#include <fstream>
using namespace std;
#define ARGLENGTH 100
int execute(char *command[]);
int main()
{
int option;
int his_size=0;
char buffer[ARGLENGTH];
char *history[his_size];
int numargs = 0;
printf("Press 1 to input from keyboard, 2 to input from file .mshrc\n");
scanf("%d",&option);
switch (option){
case 1:
while(1)
{
printf("?-> ");
if (fgets(buffer, ARGLENGTH, stdin))
{
char *outer_ptr=NULL;
for (char *buf=strtok_r(buffer, ";\n\r", &outer_ptr);
buf;
buf=strtok_r(NULL, ";\n\r", &outer_ptr) )
{
if (strcmp(buf, "exit") == 0){
return 0;
}
if (strcmp(buf, "history") == 0){
for(int a=0;a<=numargs;a++){
printf("command history: %s \n", history[a]);
}
}
char *command[1000000];
char *inner_ptr=NULL;
//int numargs = 0;
for (command[numargs] = strtok_r(buf," ",&inner_ptr);
command[numargs];
command[numargs] = strtok_r(NULL," ",&inner_ptr))
++numargs;
printf("%s \n",command[numargs]);
printf("%d \n",numargs);
if (numargs)
execute(&command[numargs]);
}
}
}
case 2:
FILE *fr;
fr=fopen("example.txt","rt");
if( fr == NULL )
{
perror("Error while opening the file.\n");
exit(EXIT_FAILURE);
}
while(fgets(buffer, ARGLENGTH, fr) != NULL ){
char *outer_ptr=NULL;
for (char *buf=strtok_r(buffer, ";\n\r", &outer_ptr);
buf;
buf=strtok_r(NULL, ";\n\r", &outer_ptr) )
{
if (strcmp(buf, "exit") == 0)
return 0;
int numargs = 0;
char *command[1000000];
char *inner_ptr=NULL;
for (command[numargs] = strtok_r(buf," ",&inner_ptr);
command[numargs];
command[numargs] = strtok_r(NULL," ",&inner_ptr))
++numargs;
if (numargs)
execute(command);
}
}
fclose(fr);
return main();
}
return 0;
}
int execute(char *command[])
{
int pid,exitstatus;
pid = fork();
if( pid==-1 ){
perror("fork failed");
exit(1);
}
else if( pid==0 ){
execvp(command[0], command);
perror("execution failed");
exit(1);
}
else {
while (wait(&exitstatus) != pid);
}
}
答案 0 :(得分:1)
问题似乎在于您将每一行作为单个命令的参数读取,然后在给出空行时执行它。如,
?-> ls
?-> -al
?->
将提供扩展目录列表。
如果您只想使用空格来分隔参数,这可能是strtok()
的一个很好的用途。我怀疑这样的事情更像你想要的东西:
int main()
{
char *command[1000000];
int numargs = 0;
char buffer[ARGLENGTH];
while(1) {
printf("?-> ", numargs);
if( fgets(buffer, ARGLENGTH, stdin) && *buffer != '\n' ) {
command[numargs++] = strtok(buffer, " \n\r");
while (command[numargs++] = strtok(NULL, " \n\r"))
;
if( numargs > 0 ){
/* command[numargs] = NULL; -- No longer needed, strtok() does this */
execute(command);
numargs = 0;
}
}
if (command[0][0] == 'e'){
break;}
}
return 0;
}
您还需要查看其他边缘案例问题:例如,空白行或以&#34; e&#34;开头的行。但这应该有助于你开始。
编辑:这里有一些更接近于我如何写这个包括在分号上拆分命令的东西。这次我做了几个风格变化,即将变量声明移动到更接近它们首次使用的位置。int main()
{
while(1)
{
printf("?-> ");
char buffer[ARGLENGTH];
if (fgets(buffer, ARGLENGTH, stdin))
{
char *outer_ptr=NULL;
for (char *buf=strtok_r(buffer, ";\n\r", &outer_ptr);
buf;
buf=strtok_r(NULL, ";\n\r", &outer_ptr) )
{
if (strcmp(buf, "e") == 0)
return 0;
int numargs = 0;
char *command[1000000];
char *inner_ptr=NULL;
for (command[numargs] = strtok_r(buf," ",&inner_ptr);
command[numargs];
command[numargs] = strtok_r(NULL," ",&inner_ptr))
++numargs;
if (numargs)
execute(command);
}
}
}
return 0;
}