Linux 用C语言实现简单的shell

发一波福利,操作系统的实验内容,大家可以借鉴一下,不过我的代码可能也存在一定的问题。

因为在一开始老师是一节一节课教的,当时并不知道后面还会用输入输出重定向,管道等一系列问题,我的兴趣也不在这个方面也没有预习,所以一来代码写的比较丑,二来没有对于代码进行一个合理的规划,写的也比较乱。

代码暂时实现到输入输出重定向,之后可能会加上管道处理等方面的程序。

如果让我重新写这段代码应该会规划的更好一点吧

/*author:Samsons
  date:2015.4.10*/
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/wait.h>

#define MAX(100)
#define LEN(100)

char *arglist[MAX];  //shell指令参数表
int num;             //shell指令参数个数

int execute(char* arglist[])//执行外部命令
{
    int error;
    error=execvp(arglist[0],arglist);
    if (error==-1) printf("failed\n");
    exit(1);
}

char* make(char *buf)//将字符串传入参数表内
{
    char *cp;
    cp=malloc(strlen(buf)+1);
    if (cp==NULL)
    {
        fprintf(stderr,"no memory\n");
        exit(1);
    }
    strcpy(cp,buf);
    return cp;
}

int my_system(char *buf,char *arglist[])//对于字符串进行分割
{
    int num,j,i,last;
    char buffer[LEN];
    num=0;
    i=0;
    while (num<MAX)
    {
        if (buf[i]==‘\n‘)
        {
            arglist[num]=NULL;
            return num;
        }
        if (buf[i]==‘ ‘) i++;
        last=i;
        while (buf[i]!=‘ ‘ && buf[i]!=‘\n‘) i++;
        for (j=last;j<i;j++) buffer[j-last]=buf[j];
        buffer[j-last]=‘\0‘;
        arglist[num++]=make(buffer);
    }
}
int inner(char *arglist[])//执行内置指令
{
    if (strcmp(arglist[0],"exit\0")==0)//exit
    {
        exit(0);
        return 1;
    }
    else
    if (strcmp(arglist[0],"pwd\0")==0)//pwd
    {
        char buf[LEN];
        getcwd(buf,sizeof(buf));//获得当前目录
        printf("Current dir is:%s\n",buf);
        return 1;
    }
    else
    if (strcmp(arglist[0],"cd\0")==0)//cd
    {
        char buf[LEN];
        if (chdir(arglist[1])>=0)
        {
            getcwd(buf,sizeof(buf));
            printf("Current dir is:%s\n",buf);
        }
        return 1;
    }
    else return 0;
}

void cat_in(char *q)//输入重定向
{
    char t[30];
    int fd;
    if (q[0]==‘<‘)
    {
        strcpy(t,q+1);
        fd=open(t,O_RDONLY);
        arglist[1]=NULL;
        if (fd==-1)
        {
            printf("file open failed\n");
            return;
        }
        dup(fd,0);
        close(fd);
    }
}

void cat_out(char *q)//输出重定向
{
    char t[30];
    int fd;
    if (q[0]==‘>‘)
    {
        strcpy(t,q+1);
        arglist[num-1]=NULL;
        num--;
        fd=open(t,O_CREAT|O_RDWR);
        if (fd==-1)
        {
            printf("file open failed\n");
            return;
        }
        dup2(fd,1);
        close(fd);
    }
}

int main()
{
    int i,pid;
    char buf[LEN];
    while (1)
    {
        fgets(buf,LEN,stdin);//读入单行指令
        num=my_system(buf,arglist);//指令分割
        int inner_flag;
        inner_flag=inner(arglist);//内置指令判断
        if (inner_flag==0)
        {
            pid=fork();//建立新的进程
            if (pid==0)
            {
                if (arglist[1]!=NULL)
                {
                    char q[LEN];
                    strcpy(q,arglist[1]);
                    cat_in(q);//输入重定向
                }
                if (arglist[num-1]!=NULL)
                {
                    char q[LEN];
                    strcpy(q,arglist[num-1]);
                    cat_out(q);//输出重定向
                }
                execute(arglist);//执行
            }
            waitpid(pid,NULL,0);
        }
    }
    return 0;
}
时间: 2024-10-11 22:35:30

Linux 用C语言实现简单的shell的相关文章

Linux 用C语言实现简单的shell(2)

不知不觉两周没有发文了,因为“一万美金的福特奖学金答辩”,ACM比赛,网络论文阅读和网络大作业一大堆事把时间冲散了,所以先写一篇博文补上之前一坑. 之前发了一篇关于linux 用C语言实现简单shell的博文,当时因为刚刚接触linux,只是处理了: 1)外部命令 2)pwd,cd,exit内置命令 3)输入输出重定向 并且代码相比较而言是一步一步添加的,代码相对来讲比较丑QAQ,所以在学完管道之后,相信不得不重新写代码才能实现了. 相比较之前的版本我对代码进行了相关的修改: 1)对于shell

Linux下C语言多线程,网络通信简单聊天程序

原文:Linux下C语言多线程,网络通信简单聊天程序 功能描述:程序应用多线程技术,可是实现1对N进行网络通信聊天.但至今没想出合适的退出机制,除了用Ctr+C.出于演示目的,这里采用UNIX域协议(文件系统套接字),程序分为客户端和服务端.应用select函数来实现异步的读写操作. 先说一下服务端:首先先创建套接字,然后绑定,接下进入一个无限循环,用accept函数,接受“连接”请求,然后调用创建线程函数,创造新的线程,进入下一个循环.这样每当有一个新的“连接”被接受都会创建一个新的线程,实现

shell 脚本实战笔记(11)--Mysql在linux下的安装和简单运维

前言: linux中安装mysql以及配置的管理, 基础的运维和管理还是需要会一些的. 这边作下笔记, 以求天天向上(^_^). 安装流程:*). 安装mysql-server1). 借助yum检索相关的mysql rpm包yum search mysqlmysql-server.x86_64 正是我们想要的 2). 安装mysql-serveryum install mysql-server.x86_64 -y默认mysql-client也安装好 3). 启动mysql服务/etc/init.

Linux系统学习笔记之 1 一个简单的shell程序

不看笔记,长时间不用自己都忘了,还是得经常看看笔记啊. 一个简单的shell程序 shell结构 1.#!指定执行脚本的shell 2.#注释行 3.命令和控制结构 创建shell程序的步骤 第一步:创建一个包含命令和控制结构的文件 第二步:修改这个文件的权限使它可以执行. 使用chmod u+x 第三步:执行shell sh /test/example.sh Shell变量 变量:是shell传递数据的一种方法,用来代表每个取值的符号名 shell有两类变量:临时变量和永久变量 临时变量是sh

UNIX/Linux下C语言的学习路线

一.工具篇 “公欲善其事,必先利其器”.编程是一门实践性很强的工作,在你以后的学习或工作中,你将常常会与以下工具打交道, 下面列出学习C语言编程常常用到的软件和工具. 1.操作系统    在UNIX或Linux系统中学习C很方便,所以在开始您的学习旅程前请先选择一个UNIX或Linux操作系统,目前可供个人免费使用的UNIX或Linux系统有FreeBSD.RedHat Linux.SUSE Linux等,而且在安装包中还提供很多实用的工具,如:gcc, make等. 如果您一直使用Window

linux 下C语言学习路线

转载:http://blog.csdn.net/xdw1985829/article/details/6817403 UNIX/Linux下C语言的学习路线. 一.工具篇 “公欲善其事,必先利其器”.编程是一门实践性很强的工作,在你以后的学习或工作中,你将常常会与以下工具打交道, 下面列出学习C语言编程常常用到的软件和工具. 1.操作系统     在UNIX或Linux系统中学习C很方便,所以在开始您的学习旅程前请先选择一个UNIX或Linux操作系统,目前可供个人免费使用的UNIX或Linux

一个简单的shell

最近按照mit的Operating System Engineering课程(6.828/Fall 2014)学习从零编写一个简单的操作系统. 第一节课的作业1就是写一个简单的shell,能够运行command,并且支持重定向(‘>’, ‘<’)和管道(‘|’),但不支持脚本编程. 课程给的源码已经实现了参数的解析 1 struct cmd * parsecmd(char *s); 该函数根据每行的命令中是否含有’>’/’<’和’|’返回不同的cmd结构: 1 struct cmd

二、Java语言的简单认识及Hello World示例

1. Java语言的简单认识 (1) Java有三个版本: a. JAVA SE (以前称J2SE):Standard Environment 标准版本: b. JAVA EE (以前称J2EE):Enterprise Environment 企业版: c. JAVA ME (以前称J2ME):Eicro Environment 微型版; (2) Java的安装目录 在前一讲中,提到安装目录中有两个文件夹,分别是jdk1.7.0_45和jre7.在"jdk1.7.0_45"文件夹的bi

Linux运维 第二阶段 (九)shell编程

Linux运维 第二阶段 (九)shell编程 一.1.基础正则表达式: *         前一个字符匹配0次或任意多次 .         匹配除了换行符外任意一个字符 ^         匹配行首,例:^Hello,匹配以Hello开头的行 $         匹配行尾,例:Hello$匹配以Hello结尾的行 []        中括号中指定的一个字符,例:[0-9].[a-z] [^]       匹配中括号字符以外的任意一个字符,例:[^0-9].[^a-z] \         转