Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C语言中的简单Shell_C_Bash_Shell_Unix - Fatal编程技术网

C语言中的简单Shell

C语言中的简单Shell,c,bash,shell,unix,C,Bash,Shell,Unix,我正在做一个学校项目,基本上是在UNIX中创建一个简单的shell。 但我的项目中有历史部分,关于历史部分的解释如下: 历史记录–此命令用于维护以前发出的命令的历史记录 o历史记录-在shell中最多打印10条最近输入的命令 啊!编号-用户应能够重复先前由发出的命令 打字!数字,其中数字指示要重复的命令 注意!1用于重复由返回的命令列表中编号为1的命令 历史,还有-1用于重复最后一个命令 我的代码历史部分在这里: #include <stdio.h> #include <uni

我正在做一个学校项目,基本上是在UNIX中创建一个简单的shell。 但我的项目中有历史部分,关于历史部分的解释如下:

历史记录–此命令用于维护以前发出的命令的历史记录

o历史记录-在shell中最多打印10条最近输入的命令

啊!编号-用户应能够重复先前由发出的命令 打字!数字,其中数字指示要重复的命令

注意!1用于重复由返回的命令列表中编号为1的命令 历史,还有-1用于重复最后一个命令

我的代码历史部分在这里:

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <limits.h>
#include <malloc.h>
#include <string.h>
#include <termios.h>
#include <errno.h>

#define CREATE_FLAGS (O_WRONLY | O_CREAT | O_APPEND)
#define CREATE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
#define CREATE_FLAG (O_WRONLY| O_CREAT| O_TRUNC)
#define MAXCHARNUM 128 
#define MAXARGNUM 32 
char *argsexec[MAXARGNUM];
char str[MAXCHARNUM];
char *path;
char *name;

struct Node
{

  pid_t pid;
  char *pname;
  int index;
  struct Node *nextPtr;
};
typedef struct Node Node;
typedef struct Node *NodePtr;

NodePtr list = NULL;

void addJob(NodePtr *currentPtr, pid_t pid, char *name, int indx)
{

  NodePtr newPtr, prePtr, curPtr;
  newPtr = malloc(sizeof(Node));

  if (newPtr != NULL )
  {

    newPtr->pid = pid;
    newPtr->pname = name;
    newPtr->index = indx;
    newPtr->nextPtr = NULL;
    prePtr = NULL;
    curPtr = *currentPtr;

    while (curPtr != NULL )
    {
      prePtr = curPtr;
      curPtr = curPtr->nextPtr;
    }

    if (prePtr == NULL )
    {
      newPtr->nextPtr = *currentPtr;
      *currentPtr = newPtr;
    }
    else
    {
      prePtr->nextPtr = newPtr;
      newPtr->nextPtr = curPtr;
    }
  }
}

void printJob(NodePtr curPtr)
{
  if (curPtr == NULL )
  {
    printf("Running: List is empty.\n");
    printf("Terminated: List is empty.\n");
  }
  else
  {
    printf("Running:\n");

    while (curPtr != NULL )
    {
      printf("[%d] --> %s\n", curPtr->index, curPtr->pname);
      curPtr = curPtr->nextPtr;
    }
    printf("Finished:\n");

    while (curPtr != NULL )
    {
      printf("[%d] --> %s (pid = %d)\n", curPtr->index, curPtr->pname,
          curPtr->pid);
      curPtr = curPtr->nextPtr;
    }
  }
}

void ioredirection()
{

  int input = -1, output = -1, append = -1;
  int k, d, fdinput, fdoutput;
  for (k = 0; argsexec[k] != NULL ; k++)
  {

    if (strcmp(argsexec[k], "<") == 0)
    {
      argsexec[k] = NULL;
      input = k;
      d = 1;
    }
    else if (strcmp(argsexec[k], ">") == 0)
    {
      argsexec[k] = NULL;
      output = k;
      d = 2;
    }
    else if (strcmp(argsexec[k], ">>") == 0)
    {
      argsexec[k] = NULL;
      append = k;
      d = 3;
    }
    if (d == 1)
    {
      fdinput = open(argsexec[input + 1], O_RDONLY, 0);
      dup2(fdinput, STDIN_FILENO);
      close(fdinput);
      execvp(argsexec[0], argsexec);
    }
    if (d == 2)
    {
      int x, y;
      char buffer[1024];

      fdinput = open(argsexec[output - 1], O_RDONLY);
      fdoutput = open(argsexec[output + 1], CREATE_FLAG, CREATE_MODE);

      dup2(fdoutput, STDOUT_FILENO);
      x = read(fdinput, buffer, 1024);
      write(fdoutput, buffer, x);

      close(fdinput);
      close(fdoutput);

      for (y = output; y < MAXARGNUM - 2; y++)
        argsexec[y] = argsexec[y + 2];
      argsexec[MAXARGNUM - 2] = NULL;
    }
    if (d == 3)
    {
      int x, y;
      char buffer[1024];

      fdinput = open(argsexec[output - 1], O_RDONLY);
      fdoutput = open(argsexec[output + 1], CREATE_FLAGS, CREATE_MODE);

      x = read(fdinput, buffer, 1024);
      write(fdoutput, buffer, x);

      close(fdinput);
      close(fdoutput);
    }
  }

}
void add_path(char **dir, const char *begin, const char *end) //do the memory allocations, and add to the specified arrays.
{
  if (end == begin)
  {
    begin = " ";
    end = begin + 1;
  }
  size_t len = end - begin;
  *dir = malloc(len + 1);
  memmove(*dir, begin, len);
  (*dir)[len] = '\0';

}

size_t tokenize(const char *path, char **dirs, size_t max_dirs, char delim) //tokenize the given input, with the given delimiter
{                        //returns the size of the splitted parts of the string.
  const char *begin = path;
  const char *end;
  size_t num_dirs = 0;

  while (num_dirs < max_dirs && (end = strchr(begin, delim)) != 0)
  {
    add_path(&dirs[num_dirs++], begin, end);
    begin = end + 1;
  }
  if (num_dirs < max_dirs && *begin != '\0')
    add_path(&dirs[num_dirs++], begin, begin + strlen(begin));
  return num_dirs;
}

void clearArgs()
{

  int i;
  for (i = 0; i < MAXARGNUM; ++i)
  {
    argsexec[i] = NULL;
  }
}

int Ampersand()
{
  int i;
  for (i = 0; argsexec[i] != NULL ; i++)
  {
    if (strcmp(argsexec[i], "&") == 0)
    {
      return 1;
    }
    else
    {
      return 0;
    }
  }
}

void Setup()
{

  while (1)
  {
    path = malloc((MAXCHARNUM + 1) * sizeof(char));
    clearArgs();

    fprintf(stderr, "333sh: ", NULL );
    gets(str);  //get the next commands

    while (strlen(str) == 0)
    { //if the user enters empty string or space, ignore this input, read again.
      fprintf(stderr, "333sh: ", NULL );
      gets(str);
    }

    size_t commands = tokenize(str, argsexec, MAXARGNUM, ' ');
    const char *path = getenv("PATH");  //get the system's path   
    ioredirection();
    char * const arguments[] =
    { argsexec[0], argsexec[1], argsexec[2], argsexec[3], argsexec[4],
        argsexec[5], argsexec[6], argsexec[7], (void*) NULL };

    name = argsexec[0];
    pid_t pid = fork();
    wait(NULL );

    if (Ampersand())
    {
      if (pid == 0)
      {
        int in = 1;
        addJob(&list, pid, name, in);

      }
    }
    if (pid == 0)
    {
      if (!Ampersand())
      {

        if (path == NULL )
        {  //execl part
          execl(path, argsexec[0], argsexec[1], argsexec[2], argsexec[3],
              argsexec[4], argsexec[5], argsexec[6], argsexec[7], NULL );
        }
        else if (strcmp(argsexec[0], "dir") == 0 && argsexec[1] == NULL )
        {
          system("ls");
        }

        else if (strcmp(argsexec[0], "clr") == 0)
        {
          system("clear");
        }
        else if (strcmp(argsexec[0], "cd") == 0 && argsexec[1] == NULL )
        {
          system("pwd");
        }
        else if (strcmp(argsexec[0], "list_jobs") == 0 && argsexec[1] == NULL )
        {
          printJob(list);

        }
        else
        {  //execvp part

          execvp(argsexec[0], arguments);
        }

      }
    }
  }
}

int main(int argc, char const *argv[])
{
  Setup();
  return 0;

}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义创建标志(O_WRONLY | O_CREATE | O_APPEND)
#定义创建模式(S|u IRUSR | S|u IWUSR | S|u IRGRP | S|IROTH)
#定义创建标志(O_WRONLY | O_CREATE | O_TRUNC)
#定义MAXCHARNUM 128
#定义MAXARGNUM 32
char*argsexec[MAXARGNUM];
char str[MAXCHARNUM];
字符*路径;
字符*名称;
结构体类型
{
pid_t pid;
char*pname;
整数指数;
结构节点*nextPtr;
};
typedef结构节点;
typedef结构节点*NodePtr;
NodePtr list=NULL;
void addJob(NodePtr*currentPtr,pid\u t pid,char*name,int indx)
{
NodePtr newPtr、prePtr、curPtr;
newPtr=malloc(sizeof(Node));
如果(newPtr!=NULL)
{
新建PTR->pid=pid;
newPtr->pname=名称;
newPtr->index=indx;
newPtr->nextPtr=NULL;
prePtr=NULL;
curPtr=*currentPtr;
while(curPtr!=NULL)
{
prePtr=curPtr;
curPtr=curPtr->nextPtr;
}
if(prePtr==NULL)
{
newPtr->nextPtr=*当前ptr;
*currentPtr=newPtr;
}
其他的
{
prePtr->nextPtr=newPtr;
newPtr->nextPtr=curPtr;
}
}
}
无效打印作业(NodePtr curPtr)
{
如果(curPtr==NULL)
{
printf(“正在运行:列表为空。\n”);
printf(“已终止:列表为空。\n”);
}
其他的
{
printf(“正在运行:\n”);
while(curPtr!=NULL)
{
printf(“[%d]-->%s\n”,curPtr->index,curPtr->pname);
curPtr=curPtr->nextPtr;
}
printf(“完成:\n”);
while(curPtr!=NULL)
{
printf(“[%d]-->%s(pid=%d)\n”,curPtr->index,curPtr->pname,
curPtr->pid);
curPtr=curPtr->nextPtr;
}
}
}
void ioredirection()
{
int-input=-1,output=-1,append=-1;
int k,d,fdinput,fdoutput;
对于(k=0;argsexec[k]!=NULL;k++)
{
if(strcmp(argsexec[k],“”)=0)
{
argsexec[k]=NULL;
输出=k;
d=2;
}
else if(strcmp(argsexec[k],“>>”==0)
{
argsexec[k]=NULL;
追加=k;
d=3;
}
如果(d==1)
{
fdinput=open(argsexec[input+1],仅限ordu,0);
dup2(fdinput,标准文件号);
关闭(FDI输入);
execvp(argsexec[0],argsexec);
}
如果(d==2)
{
int x,y;
字符缓冲区[1024];
fdinput=open(argsexec[output-1],仅限Ordu);
fdoutput=open(argsexec[output+1],创建_标志,创建_模式);
dup2(fdoutput,标准输出文件号);
x=读取(FDI输入,缓冲区,1024);
写入(输出、缓冲区、x);
关闭(FDI输入);
关闭(FD输出);
对于(y=输出;y