中国IT动力,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档 | 网通镜像
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> 程序开发 > 编程语言 > C/C++
用标准C实现shell功能
作者:未知 时间:2005-09-13 19:20 出处:ChinaUnix.net 责编:chinaitpower
              摘要:用标准C实现shell功能

下面是代码,有兴趣的试试。

[code:1:f33df78f6c]
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <string.h>
#include <errno.h>

#define SHELL_NAME "sh1"
#define PROMPT_ENVIRONMENT_VARIABLE "PROMPT"

char *prompt;

int main(int argc, char **argv) 
{
char cmd[80];
int statval;
  
/* Determine prompt value. */
if ((prompt = getenv(PROMPT_ENVIRONMENT_VARIABLE)) == NULL)
prompt = SHELL_NAME ":";

/* Process commands until exit, or death by signal. */
while (1) 
{
/* Prompt and read a command. */
printf(prompt);
gets(cmd);

/* Process built-in commands. */
if(strcasecmp(cmd, "exit") == 0)
break;

/* Process non-built-in commands. */
if(fork() == 0) {
execlp(cmd, cmd, NULL);
fprintf(stderr, "%s: Exec %s failed: %s\n", argv[0], 
cmd, strerror(errno));
exit(1);


wait(&statval);
if(WIFEXITED(statval)) 
{
if(WEXITSTATUS(statval))
{
fprintf(stderr,
"%s: child exited with status %d.\n",
argv[0], WEXITSTATUS(statval));
}
} else {
fprintf(stderr, "%s: child died unexpectedly.\n", 
argv[0]);
}
}
}
[/code:1:f33df78f6c]

 蓝色键盘 回复于:2003-05-07 18:59:05
这是对上面代码做了改进以后的版本。

[code:1:7745bfe68e]

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <errno.h>

char *parse_cmd(char *cmd, char **argarr, int *narg) {
enum states { S_START, S_IN_TOKEN, S_IN_QUOTES, S_SEMI };
int argc=0; // Arg count
int loop=1; // Loop control
enum states state = S_START; // Current state.
int lastch; // Last character encountered.
   
while (loop) {
switch (state) {
case S_START:
if (*cmd == '"') {
*argarr++ = cmd + 1;
++argc;
state = S_IN_QUOTES;
}
else if (*cmd == 0 || *cmd == ';')
loop = 0;
else if (*cmd <= ' ')
*cmd = 0;
else {
*argarr++ = cmd;
++argc;
state = S_IN_TOKEN;
}
break;
case S_IN_TOKEN:
if (*cmd == 0 || *cmd == ';')
loop = 0;
else if (*cmd <= ' ') {
*cmd=0;
state=S_START;
}
break;
case S_IN_QUOTES:
if (*cmd == 0)
loop = 0;
else if (*cmd == '"') {
*cmd = 0;
state = S_START;
}
}
cmd++;
}
*argarr = NULL;  /* store the NULL pointer */

/* Return argument count, if needed. */
if(narg != NULL) *narg = argc;

lastch = cmd[-1];
cmd[-1] = 0;
return lastch == ';' ? cmd : NULL;
}

int main(int argc, char **argv) {
char cmd[80]; // Input command area.
char *source = NULL; // Where commands to send to parser come from.
char *arg[21]; // Arg list.
int statval; // Exec status value.
char *prompt="baby:"; // Command prompt, with default.
char *test_env; // getenv return value. 
int numargs; // parse_cmd return value.
  
if (test_env=getenv("BSPROMPT"))
prompt=test_env;
while (1) {
// See if we need to get a line of input.
if(source == NULL) {
printf(prompt);
source = gets(cmd);
if(source == NULL) exit(0);  // gets rtns NULL at EOF.
}

// Get the next command.
source = parse_cmd(source, arg, &numargs);
if (numargs == 0) continue;
    
// Exit command
if (!strcmp(arg[0],"exit")) {
if (numargs==1)
exit(0);
if (numargs==2) {
if (sscanf(arg[1],"%d",&statval)!=1) {
fprintf(stderr,"%s: exit requires an "
"integer status code\n",
argv[0]);
continue;
}
exit(statval);
}
fprintf(stderr,"%s: exit takes one "
"optional parameter -integer status\n",
argv[0]);
continue;
}

// Run it.
if (fork()==0) {
execvp(arg[0],arg);
fprintf(stderr,"%s: EXEC of %s failed: %s\n",
argv[0],arg[0],strerror(errno));
exit(1);
}
wait(&statval);
if (WIFEXITED(statval)) {
if (WEXITSTATUS(statval))
fprintf(stderr,"%s: child exited with "
"status %d\n", argv[0],
WEXITSTATUS(statval));
} else {
fprintf(stderr,"%s: child died unexpectedly\n",
argv[0]);
}
}
}
[/code:1:7745bfe68e]

 蓝色键盘 回复于:2003-05-22 19:25:37
up!有兴趣的请来分析!

 小飞爱使申华 回复于:2003-05-23 07:06:40
太感谢了,找对组织了!

 Law 回复于:2003-05-23 11:18:06
太难了,看不懂啊!

 小飞爱使申华 回复于:2003-05-23 11:56:57
blue keyboard老大,第二个程序compile都过不了啊,请帮忙看看。

 蓝色键盘 回复于:2003-05-23 17:18:23
提示什么错误??

你的环境是??

 wangrujun 回复于:2003-05-29 10:05:20
我运行没问题
能简单讲一下吗?

 acb 回复于:2003-05-30 08:41:14
也许是注释的问题。有的环境中,//不能被正确编译。要用/* */

 小飞爱使申华 回复于:2003-05-30 09:19:48
[quote:03e9a0599b="acb"]也许是注释的问题。有的环境中,//不能被正确编译。要用/* */[/quote:03e9a0599b]     

相当正确! 

 zhazha518 回复于:2003-06-10 15:43:21
老大你是在什么环境下写的啊,我的在win下用的vc++编译器,找不到你的第一个头文件啊

 蓝色键盘 回复于:2003-06-10 16:32:55
windows没有unistd.h这个头文件。

 shangxd 回复于:2003-06-16 20:24:53
非常感谢。
但是还有点小问题,比如用cd命令的时候会出现错误。
但是有了这个模板真的少花不少时间,再次感谢:)

 alphaliu 回复于:2003-06-17 11:01:09
up

 蓝色键盘 回复于:2003-06-30 15:04:54
这个是些实现简单的shell功能的demo。

我想bash真正的实现应该不是这个思想,要比这个复杂的多。

大鹰,你有bash的源码,呵呵

发我邮箱cobrakings@263.net

 e4gle 回复于:2003-06-30 15:08:52
我ft,bash的源代码到处都是啊,哈哈,它本身就是开放的

 htldm 回复于:2003-06-29 09:50:23
真正的精华

 jacical2002 回复于:2003-06-29 21:50:14
我是新手,请多指教.  
    这个程序是可在任意C环境下调试成功麽?

 蓝色键盘 回复于:2003-06-30 13:28:07
看看头文件,主要是Unix下c编译环境。

 e4gle 回复于:2003-06-30 14:56:30
这代码有点像apue里面的例子,我很早就实现过,做好一个shell其实挺困难,bash是一个非常成功的shell,而且代码非常复杂,其实就是体力活,要处理很多东西,技术上倒没什么难度

 蓝色键盘 回复于:2003-06-30 15:14:53
以前down过,不全啊,可能版本也有点老了。

现在懒得找,发给我不更省事.



 无双 回复于:2003-06-30 15:16:38
主要是实现原理

一个bash要实现管道、后台运行重定向功能

如果看bash的话还大了

 蓝色键盘 回复于:2003-06-30 15:26:02
bash源码我没看过。但是估计实现原理没有我提供的那么简单吧 



 e4gle 回复于:2003-06-30 16:05:36
那当然,复杂的多了,而且最新版的bash还把suid的安全问题考虑进去了

 蓝色键盘 回复于:2003-06-30 16:39:39
恩,刚down了一个bash,看日期大多数是2002更新的。有点晕。

 蓝色键盘 回复于:2003-06-30 16:42:58
大鹰,cygwin这个软件大概是怎么实现的。

 e4gle 回复于:2003-06-30 17:03:22
那个也很简单啊,转换那些不兼容的函数库呗,但是是有局限性的,只能编译与体系无关的c代码

 无双 回复于:2003-06-30 23:18:55

大鹰你什么都知道啊

内核看过
bash源码也看过

我觉得如果想深入研究内核的话都够内的了

 henngy 回复于:2003-08-28 09:34:33
有关于目录复制的源码吗??

 yujf 回复于:2003-08-29 11:47:31
厉害,我去试试

 fyitang 回复于:2003-09-05 12:32:49
能不能帮我改进一下可以一次处理多个命令,彼此用分号隔开。且可以前、后台执行?非常感激。
我的邮箱是fyitang@tom. com

关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 chinaitpower.com All rights reserved. www.chinaitpower.com 版权所有