| 蓝色键盘 回复于: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
|