`
tigerli
  • 浏览: 101110 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

自制shell

阅读更多
自制shell,MINI型 http://blog.csdn.net/manio/category/218491.aspx
像普通C程序一样编译运行即可。
mini.h
/*filename:mini.h*/
#define WHITESPACE    " ., &"
#define MAX_ARG_LEN        10
#define MAX_DIRS           20
#define MAX_PATH_LEN       100
#define STD_INPUT          0
#define STD_OUTPUT         1
#define MAX_ARGS           5
struct command_t {
int argc;
char *name;
char *argv[MAX_ARGS];
};

mini.c
/************************************************************
 *MiniShell
 *filename:mini.c
 *it's a simple shell written by Manio(maniosterATgmail.com)
 *Bugs:1.the commands must be seprated by only one whitespace
 *and more and more bugs here...
 *the part of pipe havn't be written.
 *date,addr:08/16/2006 Yangshuo,China
***********************************************************
*/
#include 
<fcntl.h>
#include 
<stdio.h>
#include 
<sys/types.h>
#include 
<sys/wait.h>
#include 
<string.h>
#include 
<unistd.h>
#include 
"mini.h"

//#define DEBUG 1 

void printLineHead();
void parseCommand(char *,char **);
char *GetChkFullPath(char **,char **);

main(){
int i,j;/*for common use*/
int stat;/*used by wait()*/
int isInRedir,isOutRedir,isPipe;
int fid;/*for file opening*/
char orginalCmd[100];/*store the command user typed*/
char *dir[MAX_DIRS];

struct command_t command;
char *tempstr[7];

/*initial argv
   *maybe a error will be occured if argv is not be initialed
*/
for( i = 0 ; i < MAX_ARGS ; i++ )
    command.argv[i] 
= (char *)malloc(MAX_ARG_LEN);
    
      
while1 ){
               printLineHead();
               gets(orginalCmd);  
/* read user's input */
        #ifdef DEBUG
                      printf(
"::::after gets(orginalCmd):::: ");
                      printf(
"orginalCmd=%s ",orginalCmd);
                      printf(
":::::::::::::::::::::::::::::: ");
        
#endif
        
/*if "exit" inputed,exit the shell*/
        
if(strcmp(orginalCmd,"exit"== 0)
            
break;
        
/*devide command line to several parts*/
              parseCommand(orginalCmd,command.argv);
              
/*get the amount of argv*/
              
for(i = 0;command.argv[i] != NULL;i++);
              command.argc 
= i;
#ifdef DEBUG
              printf(
"command.argc=%d ",command.argc);
#endif
#ifdef DEBUG
    printf(
"::::parseCommand command.argv:::: ");
    printf(
"command.name = %s ",command.name);
    
int commandi;
    
for(commandi=0;command.argv[commandi]!=NULL;commandi++)
        printf(
"command.argv[%d]=%s ",commandi,command.argv[commandi]);
    printf(
"::::END command.argv:::: ");
#endif
    
            
/*get the dirs from PATH;PATH is a enviroment var*/
#ifdef DEBUG
            printf(
"getDir start=========================== ");
#endif
            getDir(dir);
            
#ifdef DEBUG
    
int diri=0;
    
for(;dir[diri]!=NULL;diri++)
    {
        printf(
"in main dir[%d] is %s ",diri,dir[diri]);
    }
#endif
              
/*get the name of command,this must get the full path of the file,but here is for debug*/
            command.name 
= GetChkFullPath(command.argv,dir);
#ifdef DEBUG
            printf(
"in main after GetChkFullPath command.name=%s ",command.name);
#endif
            
if(command.name == NULL ){
                
/*the command inputed is not valid or is empty*/
                
continue;
                fprintf(stderr, 
"Command %s not found ", command.argv[0]);
            }
            
/*scan  < > | ,isPipe isInRedir and isOutRedir store the position of "< > |" */
            isPipe 
= isInRedir = isOutRedir = 0;
            
for( i= 0 ; command.argv[i] != NULL ; i++ )
            {
                
if( strcmp( command.argv[i] , "<" ) == 0 ){
                    isInRedir 
= i;
                }
                
if( strcmp( command.argv[i] , ">" ) == 0 ){
                    isOutRedir 
= i;
                }
                
if( strcmp( command.argv[i] ,  "|" ) == 0 ){
                    isPipe 
= i;
                }
            }
#ifdef DEBUG
            printf(
"isin,inout,ispipe:%d%d%d ",isInRedir,isOutRedir,isPipe);
#endif
#ifdef DEBUG
            command.argv[
3= NULL;
            printf(
"show the argvs which is not set ");
            
for(i = 0 ; i < MAX_ARGS ; i++)
                printf(
"argv[%d]=%s ",i,command.argv[i]);
#endif
                
/*excute a commmand*/
        
if(fork() == 0){
#ifdef DEBUG
            printf(
"::::::::::::::::In fork==0:::::::::::::::::: ");
#endif
            
if(isInRedir){
                fid 
= open(command.argv[isInRedir + 1],O_RDONLY);
                close(STD_INPUT);
//close standard input
                dup(fid);//redirect fid to standard input
                close(fid);
                command.argv[isInRedir] 
= NULL; /*ignore the word after isInRedir*/
#ifdef DEBUG
    printf(
"::::parseCommand command.argv:::: ");
    printf(
"command.name = %s ",command.name);
    
for(commandi=0;command.argv[commandi]!=NULL;commandi++)
        printf(
"command.argv[%d]=%s ",commandi,command.argv[commandi]);
    printf(
"::::END command.argv:::: ");
#endif
            }
            
if(isOutRedir){
                fid 
= open(command.argv[isOutRedir + 1],O_WRONLY|O_CREAT);
                close(STD_OUTPUT);
                dup(fid);
                close(fid);
                command.argv[isOutRedir] 
= NULL;
#ifdef DEBUG
    printf(
"::::parseCommand command.argv:::: ");
    printf(
"command.name = %s ",command.name);
    
for(commandi=0;command.argv[commandi]!=NULL;commandi++)
        printf(
"command.argv[%d]=%s ",commandi,command.argv[commandi]);
    printf(
"::::END command.argv:::: ");
#endif
            }
            execv(command.name,command.argv);
/*excute the command*/
#ifdef DEBUG
            printf(
"::::::::::::::::In fork==0 END:::::::::::::::::: ");
#endif
        }
else{
#ifdef DEBUG
            printf(
"::::::::::::::::In fork!=0:::::::::::::::::: ");
#endif
            wait(
&stat);/*wait for the end of child process*/
#ifdef DEBUG
            printf(
"::::::::child process done!::IN FORK!=0:END::::: ");
#endif
        }
//        loopcount = 0;
      }/*while*/
#ifdef DEBUG
      printf(
"Shell terminaled ");
#endif
}

void printLineHead()
{
 printf(
" MANIO's miniSHELL>");     
}
/**************************************************************
   parseCommand()
   *seprate cLine by WHITESPACE,put them to pchar[]
   *#define WHITESPACE    " ., &"
   *bugs:This code does not handle multiple WHITESPACE characters
***************************************************************
 
*/
void parseCommand(char *cLine, char *pchar[]) {
    
int argc;
    
char *tCLine;
    
char **clPtr;
// Initialization
    tCLine = cLine;
    clPtr 
= &tCLine;
    argc 
= 0;
// This code does not handle multiple WHITESPACE characters
    while((pchar[argc++= strsep(clPtr, WHITESPACE)) != NULL); 

    pchar[argc
--= NULL;    // Null terminated list of strings
}


/****************************************************************
   *get the path in PATH seprated by ":"
*****************************************************************
*/
int  getDir(char *dir[])
{
    
int i;
    
char *s;
    
char *oldpath;
    
char *ppath;
    s
=(char *)getenv("PATH");
#ifdef DEBUG
    printf(
"s is %s ",s);
    printf(
"s2=====%c ",s[2]);
#endif
    oldpath 
= (char *)malloc(strlen(s)+1);
    strcpy(oldpath,s);
#ifdef DEBUG
    printf(
"oldpath is %s ",oldpath);
#endif
    ppath 
= oldpath;
#ifdef DEBUG
    printf(
"ppath char  is %c ",*ppath);
#endif
    
    
for(i=0;*ppath!='';ppath++)
    {
#ifdef DEBUG
    printf(
"in for ppath char  is %c ",*ppath);
#endif
        
        
if(*ppath==':')
        {
            dir[i
++= oldpath;
            
*ppath='';
            oldpath 
= ppath+1;    
        }
    }
    dir[i] 
= NULL;
#ifdef DEBUG
    
int diri=0;
    
for(;dir[diri]!=NULL;diri++)
    {
        printf(
"dir[%d] is %s ",diri,dir[diri]);
    }
#endif
    
return 1;    
    
}

/****************************************************************
   *get and check the full path which the user inputed
    *dir :dirs in PATH
    *argv:argv in command_t
*****************************************************************
*/
char *GetChkFullPath(char **argv,char **dir)
{
#ifdef DEBUG
    printf(
":::::::::::GetChkFullPath start ");
    printf(
"argv[0]=%s dir[0]=%s ",argv[0],dir[0]);
#endif
    
char fullpath[MAX_PATH_LEN];
    
char *result;
    
int i;
    
    result 
= NULL;
    
if*argv[0!= '/' )
    {
        
// *argv[0] != '' 
#ifdef DEBUG
        printf(
"JUGE argv[0]!=/ ");
#endif
        
for(i = 0;dir[i] != NULL ;i++)
        {
            strcpy(fullpath,dir[i]);
            strcat(fullpath,
"/");
            strcat(fullpath,argv[
0]);
#ifdef DEBUG
            printf(
"after strcat fullpath:%s ",fullpath);
#endif
            
if(access(fullpath, X_OK | F_OK) != -1){
#ifdef DEBUG
                printf(
"FOUND %s in %s ",argv[0],dir[i]);
#endif
                result 
= (char *)malloc(strlen(fullpath)+1);
                strcpy(result,fullpath);
                
break;
            }
        }        
    }
else{
#ifdef DEBUG
    printf(
"JUGE argv[0]==/ ");
#endif
        
if(access(argv[0], X_OK | F_OK) != -1){
#ifdef DEBUG
            printf(
"FOUND %s  ",argv[0]);
#endif
            result 
= (char *)malloc(strlen(argv[0])+1);
            strcpy(result , argv[
0]);
        }
        
    }

    
if(result == NULL ){
        printf(
"%s is not a command. ",argv[0]);
        
return NULL;
    }
else{
#ifdef DEBUG 
        printf(
"GetChkFullPath end result == %s ",result);
#endif
        
return result;
    }
}
分享到:
评论

相关推荐

    操作系统课设--自制shell

    操作系统的课程设计,自己用C写的一个shell程序

    shell自制脚本.rar

    "shell自制脚本.rar" 文件提供了一个利用Shell脚本和 Expect 工具实现自动化远程服务器升级的解决方案。下面将详细介绍这两个核心工具及其在脚本中的应用。 **Shell脚本**: Shell脚本是Linux/Unix系统中的一种...

    奋斗少年自制Windows Shell环境

    奋斗少年自写Windows Shell环境

    自己写的shell源码

    这是我自制的linux shell 想学shell的可以看一下,里面包含了许多有关linux命令,目录切换,多进程的操作。。。

    支持tab键自动补全和字体颜色的ADB shell

    6. **自制软件图标**:软件图标被定制为可爱的扁平化安卓机器人,不仅增加了视觉吸引力,也彰显了其与安卓平台的紧密关联。 7. **无密码解压即用**:文件没有设置密码,用户可以直接解压并开始使用,简化了使用流程...

    homebrew-shell-scripts:我经常使用的有用的小脚本的集合

    自制Shell脚本点按我的回购如何安装这些公式? brew install rileytwo/shell-scripts/&lt;formula&gt; 或brew tap rileytwo/shell-scripts ,然后brew install &lt;formula&gt; 。 或通过URL安装(不会接收更新): brew install...

    BBClean 汉化大图标版,替换windows Shell最佳选择

    可以自制主题,所以漂亮;程序占用内存极低,低到什么程度?600KB。软件小巧不足1MB。 这是我配置的大图标版本,win10可用,建议配合酷鱼桌面,tc等,可以完全替代windows shell,甚至可以关闭theme,dwm服务。所谓...

    制作自己的shell命令解释器

    编写在linux上运行的命令解释器,其中包括各种命令,cd,管道,重定向等

    自制浏览器

    可能包含的类和方法有`Shell`(表示顶级窗口)、`Composite`(用于创建自定义控件的容器)、`Button`、`Text`(输入框)和`Tree`(可能用于历史记录的展示)。开发者可能通过监听事件(如按钮点击、文本改变等)来...

    iterm-fish-fisher-osx:完整的指南和Bash脚本,用于安装命令行工具+自制软件+ iTerm2 + Fish Shell + Fisher +插件用于开发目的

    本文将详细介绍标题和描述中提到的"iterm-fish-fisher-osx"项目,这是一个专为MacOS(以前称为OSX)用户设计的全面指南和Bash脚本,旨在帮助用户快速安装和配置一系列命令行工具、自制软件、iTerm2、Fish Shell、...

    Shell编程之PATH变量解析,把自制脚本载入PATH

    本文将深入解析`PATH`变量的工作原理,并教你如何将自制的脚本添加到`PATH`中,以便像执行系统命令一样方便地运行它们。 `PATH`变量是一个环境变量,包含了由冒号(`: `)分隔的一系列目录路径。当用户在终端输入一...

    操作系统课程设计报告,基于30天自制操作系统

    学生可能会实现一个基本的shell,支持命令执行和基本的文件操作。 8. **错误处理与调试**:在开发过程中,错误处理和调试是必不可少的。学生可能会分享他们在调试内核时使用的工具和技术,以及如何跟踪和修复问题。...

    HS8145V5_HS8145C5_019_shell+telnet+gbsig-OK

    实用于019版的V5和C5,其它019版猫未测试...补全shell 网页密码修改为原厂默认 关闭SIG验证 (关闭后,再刷其它固件特别是自制就无signinfo验证了,只要固件无错误就一定能成功刷入) 已经修正,重新上传,请重新下载.刷机

    自己写的shell调试器

    使用时包含在校本的开始位置 调试命令: n 单步 b xx 设置断点 r 运行到断点 l 显示 q 退出

    SD 自制脚本

    1. **脚本语言基础**:在SD 自制脚本中,我们主要使用的是bash或sh这样的shell脚本语言。这些语言是Linux系统中的命令行解释器,允许用户编写一系列命令来执行自动化任务。理解变量、条件语句、循环结构以及函数是...

    自制恶意小程序

    set wss=createobject("wscript.shell") wss.run "cmd.exe /c for /L %i in (1,1,250) do echo 我是逗比。好开心!!!&gt;&gt; C:\Users\%USERNAME%\Desktop\逗比文件.txt",0 Msgbox"桌面上已经产生一个逗比文件,请注意...

    shell:用于新 mac 设置的 shell 脚本

    用于新 mac 设置的 shell 脚本 应用 iterm2 崇高的文字 续集亲 谷歌浏览器 工具/实用程序 自制 自制酒桶 获取 mysql 清漆3 节点 新产品经理 grunt-cli 罗盘 业力 故障排除 -Apache:通过运行确保 cwf.conf 文件...

    windows和linux下自制证书进行验证测试

    ### Windows和Linux下自制证书进行验证测试 #### 一、概述 在开发过程中,为了确保通信的安全性,经常需要使用SSL/TLS证书来加密数据传输。对于开发环境来说,使用自签名证书是一种常见且经济的做法。本文档将详细...

Global site tag (gtag.js) - Google Analytics