Linux 用C语言实现简单的shell(1)
发一波福利,操作系统的实验内容,大家可以借鉴一下,不过我的代码可能也存在一定的问题。
因为在一开始老师是一节一节课教的,当时并不知道后面还会用输入输出重定向,管道等一系列问题,我的兴趣也不在这个方面也没有预习,所以一来代码写的比较丑,二来没有对于代码进行一个合理的规划,写的也比较乱。
代码暂时实现到输入输出重定向,之后可能会加上管道处理等方面的程序。
如果让我重新写这段代码应该会规划的更好一点吧
/*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[],arglist);
if (error==-) printf("failed\n");
exit();
} char* make(char *buf)//将字符串传入参数表内
{
char *cp;
cp=malloc(strlen(buf)+);
if (cp==NULL)
{
fprintf(stderr,"no memory\n");
exit();
}
strcpy(cp,buf);
return cp;
} int my_system(char *buf,char *arglist[])//对于字符串进行分割
{
int num,j,i,last;
char buffer[LEN];
num=;
i=;
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[],"exit\0")==)//exit
{
exit();
return ;
}
else
if (strcmp(arglist[],"pwd\0")==)//pwd
{
char buf[LEN];
getcwd(buf,sizeof(buf));//获得当前目录
printf("Current dir is:%s\n",buf);
return ;
}
else
if (strcmp(arglist[],"cd\0")==)//cd
{
char buf[LEN];
if (chdir(arglist[])>=)
{
getcwd(buf,sizeof(buf));
printf("Current dir is:%s\n",buf);
}
return ;
}
else return ;
} void cat_in(char *q)//输入重定向
{
char t[];
int fd;
if (q[]=='<')
{
strcpy(t,q+);
fd=open(t,O_RDONLY);
arglist[]=NULL;
if (fd==-)
{
printf("file open failed\n");
return;
}
dup(fd,);
close(fd);
}
} void cat_out(char *q)//输出重定向
{
char t[];
int fd;
if (q[]=='>')
{
strcpy(t,q+);
arglist[num-]=NULL;
num--;
fd=open(t,O_CREAT|O_RDWR);
if (fd==-)
{
printf("file open failed\n");
return;
}
dup2(fd,);
close(fd);
}
} int main()
{
int i,pid;
char buf[LEN];
while ()
{
fgets(buf,LEN,stdin);//读入单行指令
num=my_system(buf,arglist);//指令分割
int inner_flag;
inner_flag=inner(arglist);//内置指令判断
if (inner_flag==)
{
pid=fork();//建立新的进程
if (pid==)
{
if (arglist[]!=NULL)
{
char q[LEN];
strcpy(q,arglist[]);
cat_in(q);//输入重定向
}
if (arglist[num-]!=NULL)
{
char q[LEN];
strcpy(q,arglist[num-]);
cat_out(q);//输出重定向
}
execute(arglist);//执行
}
waitpid(pid,NULL,);
}
}
return ;
}
Linux 用C语言实现简单的shell(1)的更多相关文章
- Linux 用C语言实现简单的shell(2)
不知不觉两周没有发文了,因为“一万美金的福特奖学金答辩”,ACM比赛,网络论文阅读和网络大作业一大堆事把时间冲散了,所以先写一篇博文补上之前一坑. 之前发了一篇关于linux 用C语言实现简单shel ...
- linux下c语言实现简单----线程池
这两天刚好看完linux&c这本书的进程线程部分,学长建议可以用c语言实现一个简单的线程池,也是对线程知识的一个回顾与应用.线程的优点有好多,它是"轻量级的进程",所需资源 ...
- 如何在linux下编写一个简单的Shell脚本程序
在了解了linux终端和其搭配的基本Shell(默认为bash)的基础下,我们就可以在终端中用vi/vim编辑器编写一个shell的脚本程序了 Shell既为一种命令解释解释工具,又是一种脚本编程语言 ...
- Linux系统学习笔记之 1 一个简单的shell程序
不看笔记,长时间不用自己都忘了,还是得经常看看笔记啊. 一个简单的shell程序 shell结构 1.#!指定执行脚本的shell 2.#注释行 3.命令和控制结构 创建shell程序的步骤 第一步: ...
- linux 下C语言学习路线
UNIX/Linux下C语言的学习路线.一.工具篇“公欲善其事,必先利其器”.编程是一门实践性很强的工作,在你以后的学习或工作中,你将常常会与以下工具打交道, 下面列出学习C语言编程常常用到的软件和工 ...
- Unix和Linux下C语言学习指南
转自:http://www.linuxdiyf.com/viewarticle.php?id=174074 Unix和Linux下C语言学习指南 引言 尽管 C 语言问世已近 30 年,但它的魅力仍未 ...
- Linux学习之路(三)Shell脚本初探
本文参考链接:http://www.runoob.com/linux/linux-shell.html 基本说明 Shell脚本(shell script)是一种为shell编写的脚本程序.其中she ...
- Linux内核分析— —构造一个简单的Linux系统MenuOS(20135213林涵锦)
Linux内核分析— —构造一个简单的Linux系统MenuOS 实验内容 Linux内核的启动过程,从start_kernel到init进程启动 使用实验楼的虚拟机打开shell cd LinuxK ...
- 如何写一个简单的shell
如何写一个简单的shell 看完<UNIX环境高级编程>后我就一直想写一个简单的shell来作为练习,因为有事断断续续的写了好几个月,如今写了差不多来总结一下. 源代码放在了Github: ...
随机推荐
- 关于 Can't connect to MySQL server on 'localhost' (10061) 的一个解决方案
问题描述: 使用Navicat for mysql 无法远程连接到本地数据库,提示Can't connect to MySQL server on 'localhost' (10038) . 本地服务 ...
- poi导出excel出现本工作薄不能再使用其他新字体的解决方法
最近使用POI处理EXCEL,当处理的单元格太多时,就会出现,本工作薄使用字体过多,不能再使用其他新的字体的是提示. 网上很多方法告诉我,要怎么修改excel文件,但是这个解决不了问题啊,难道让客户去 ...
- Win8.1下运行环境/配置问题解决方案总结
目录 1.运行 adb shell 时报错" adb server version (26) doesn't match this client (39); killing... " ...
- Mongoose 利用实现HTTP服务
嘛.... 注意:这里是使用mongoose实现HTTP服务,非数据库使用. 最近由于需要使用HTTP服务端,原先是使用的Qt框架实现的HTTP服务端,然后发现有些缺陷导致我不得不放弃这个框架,也不是 ...
- NodeManager 启动一会儿挂掉
[root@hadoop1 hadoop-2.8.5]# less logs/yarn-root-nodemanager-hadoop1.log 查看日志发现 hostname配置错误 [root@ ...
- initUrl方法
private String initUrl(String preurl,String taskurl) { if(JavaUtil.match(taskurl, "/[a-z]+$&quo ...
- sharepoint搜索配置问题
配置sharepoint 爬网内容源,如我们有4台前端服务器,集群域名为eds.jd.com,2台用于爬网前端服务器,集群域名为crawl.eds.jd.com 配置内容源的时候,将地址配为: 结果一 ...
- nvme ioctl解密
对于Nvme SSD,我们有的时候会用到ioctl系统调用,该调用的流程是怎样的呢? 首先,在注册nvme设备的时候,会初始化该设备的注册了file operations: static const ...
- 轻量ORM-SqlRepoEx (十四)最佳实践之Dapper(1)
简介:SqlRepoEx是 .Net平台下兼容.NET Standard 2.0人一个轻型的ORM.解决了Lambda转Sql语句这一难题,SqlRepoEx使用的是Lambda表达式,所以,对c#程 ...
- iOS中Block循环引用的问题
说到循环引用问题,想必大家都碰到过吧,比如在使用Block的时候,使用__weakSelf来代替self解决等,但是对于这个,还是有不少可以探索的点,下面我就来说下,希望对大家有所帮助. 是否所有的B ...