c语言模仿bash的程序

Posted 吾乃世间奇才

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c语言模仿bash的程序相关的知识,希望对你有一定的参考价值。

伪bash:半成品

#include <stdio.h>
#include <string.h>
#include <shadow.h>
#include <crypt.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#define CMDMAX 7
#define LOG_W(fmt, args...) printf("\\033[33m[Main][%s@%d]:\\033[0m" fmt , __func__, __LINE__, ## args)

struct mybash_obj;
struct cmd_object;

struct cmd_object
	char cmd[32];
	int (*func)(struct mybash_obj *pbash);
;
struct mybash_obj
	char *curdir;
	char *cmd;
	char *param1;
	void (*init)(struct mybash_obj*);
	void (*exit)(struct mybash_obj*);
	void (*parse)(char *str, struct mybash_obj*);
	int  (*mach_cmd)(int num, struct mybash_obj*);
	void (*exec_cmd)(int num, struct mybash_obj*);
	struct cmd_object *cmdobj;
;

int fileis(char *path, char *name)

  DIR *dir;
  if ((dir=opendir(path)) == 0)
	  return -1;
 
  struct dirent *stdinfo;
 
	while ((stdinfo=readdir(dir))) 
  		if(!strcmp(stdinfo->d_name, name))
			return stdinfo->d_type;
	
  closedir(dir);   // 关闭目录指针
  return 0;


int lsfunc(struct mybash_obj *p)

  DIR *dir;
  if ((dir=opendir(p->curdir)) == 0)
	  return -1;
 
  struct dirent *stdinfo;
 
  while ((stdinfo=readdir(dir)))
  
	switch(stdinfo->d_type) 
		case DT_DIR:
			printf("DIR        %s\\n", stdinfo->d_name); //目录
			break;
		case DT_REG:
			printf("REGFILE    %s\\n", stdinfo->d_name); //普通文件
			break;
		delault:
			//man readdir
			break;
	
  
 
  closedir(dir);   // 关闭目录指针


int cdfunc(struct mybash_obj *pbash)

	//LOG_W("cd func\\n");
	int len = strlen(pbash->curdir);
	int i;
	int ret = -1;
	if(!strcmp(pbash->param1, "..")) 
		if(strcmp(pbash->curdir, "/")) 
			for(i=len-1; pbash->curdir[i] != '/'; i--) 
				pbash->curdir[i] = '\\0';
			
			if(i != 0)
			pbash->curdir[i] = '\\0';
		
	 else if (!strcmp(pbash->param1, ".")) 
	 else
		ret = fileis(pbash->curdir, pbash->param1);
		if(ret == DT_DIR) 
			if(strcmp(pbash->curdir, "/"))
				strcat(pbash->curdir, "/");
			strcat(pbash->curdir, pbash->param1);
		 else 
			printf("No such Dir\\n");
		
	
	LOG_W("currnet dir is %s\\n", pbash->curdir);
	return 0;




int pwdfunc(struct mybash_obj *pbash)

	printf("no nothing todo\\n");

int putsfunc(struct mybash_obj *pbash)

	printf("no nothing todo\\n");

int getsfunc(struct mybash_obj *pbash)

	printf("no nothing todo\\n");

int rm(struct mybash_obj *pbash)

	printf("no nothing todo\\n");

int mkdir(struct mybash_obj *pbash)

	printf("no nothing todo\\n");


void initbash(struct mybash_obj *p)

	char *path;
	path=getcwd(NULL,0);
	LOG_W("th pathis %s\\n", path);
	p->curdir = (char *)malloc(512 * sizeof(char));
	p->cmd = (char *)malloc(64 * sizeof(char));
	p->param1 = (char *)malloc(128 * sizeof(char));
	memset(p->curdir, 0, 512 * sizeof(char));
	strcpy(p->curdir, path);
	free(path);
	printf("bash init \\n");


void exitbash(struct mybash_obj* p)

	free(p->curdir);
	free(p->cmd);
	free(p->param1);
	printf("bash exit \\n");


void parsefunc(char *str, struct mybash_obj* p)

	memset(p->cmd, 0, sizeof(p->cmd));
	memset(p->param1, 0, sizeof(p->param1));
	sscanf(str, "%s %s", p->cmd, p->param1);
//	LOG_W("cmd is (%s), param1 is (%s)\\n", p->cmd, p->param1);

int  mach_cmdfunc(int num, struct mybash_obj* p)

	if(strcmp((p->cmdobj[num]).cmd, p->cmd))
		return 0;
	else
		return 1;


void exec_cmd_func(int num, struct mybash_obj *pbash)

	pbash->cmdobj[num].func(pbash);




struct cmd_object cmd_obj[CMDMAX]= 
	"cd", cdfunc,
	"ls", lsfunc,
	"pwd", pwdfunc,
	"puts", putsfunc,
	"gets", getsfunc,
	"rm", rm,
	"mkdir", mkdir
;
struct mybash_obj bashobj = 
	.init = initbash,//初始化伪bash
	.exit = exitbash,//退出伪bash
	.parse = parsefunc,//解析用户的输入,解析成为本个结构体的char *cmd和char *param1;cmd是命令,param1是参数比如cd word,cmd是"cd", param1是"work"
	.mach_cmd = mach_cmdfunc,//匹配与命令,返回命令表的索引,命令表是cmd_obj[CMDMAX];
	.exec_cmd = exec_cmd_func,//执行相对应索引的命令
	.cmdobj = cmd_obj//命令表
;

int main()

	char str[512] = "";
	int i;
	char ch;
	bashobj.init(&bashobj);
	while(1) 
		memset(str, 0, sizeof(str));
		printf("$: ");
		scanf("%[^\\n]", str);
		getchar();
		bashobj.parse(str, &bashobj);
		for(i=0; i < CMDMAX; i++) 
			if(bashobj.mach_cmd(i, &bashobj)) 
				bashobj.exec_cmd(i,&bashobj);
			
		
	
	bashobj.exit(&bashobj);
	return 0;

只实现了两个命令,ls和cd,

以上是关于c语言模仿bash的程序的主要内容,如果未能解决你的问题,请参考以下文章

用C语言模仿Python函数

Javascript模仿C语言的链表实现(增删改查),并且使用控制台输入输出

Part2 Linux Bash Shell变量和重定向

bash脚本编程学习笔记

bash

bash shell编程快速入门教程