- 论坛徽章:
- 0
|
明天本来我要把这段期间做的一个小东西,给我们部门的人展示一下,结果晚上8点钟测试机OVER了,恢复它到了晚上11点才回来,太累了。本来今天不想写了,没想到有这么多人支持,眼泪哗哗的,再累也不觉得了!呵呵,废话少说,捞干的!
接着上次那个shell,我们再改进一下它,作个“强化版”。其实是打肿脸充胖子,如果说bash是宝马7系(我今生奋斗的目标)的话,前面我们那个也就是台破自行车,速度不行,还没闸(无法自己退出),还容易出车祸(有安全隐患)。但好歹也是辆车,它能上路也能跑。今天我们给前后胎打点气,让它再提提速。(火车服务那么差,还天天提速呢,咱自行车咋了?)
我们知道,每个UNIX用户都有自己的环境变量。比如$HOME,$SHELL,$PAHT啦等等。这里不多说这个了,不太了解的朋友可以看看别的关于shell的东西。我只说一点如果你是bash或csh的话输入
就可以看到你的所有环境变量了。有人可能要问,这不是全部吧,怎么没看到PS1,PS2什么的呀。注意环境变量和shell变量是两码事,它们是shell变量。你也可以输入
的话可以看到你所有的环境变量和shell变量。这里面就有它们了吧。
接下来我们先做一个读取环境变量并打印出来的程序
- #include<stdio.h>
- int main ( int argc , char *argv[] , char *envp[] )
- {
- int i;
- for( i=0 ; envp[i]!=NULL ; i++ )
- {
- printf( "%s\n" , envp[i] );
- }
- return 0;
- }
复制代码
编译,执行
- $./a.out
- TERM=xterm
- SHELL=/bin/bash
- HISTSIZE=1000
- SSH_CLIENT=192.168.1.10 2115 22
- QTDIR=/usr/lib/qt-3.3
- QTINC=/usr/lib/qt-3.3/include
- SSH_TTY=/dev/pts/1
- DISPLAY=:0.0
- .
- .
- 以及你的系统中其它的环境变量。
- .
复制代码
再看看我们上面说的那个$env命令,看看结果是不是一样的。10行不到的东西就能搞定复杂的环境变量是不是很神奇。想一想它是怎么运行的:当输入./a.out并回车,shell就fork一个子进程,子进程去调用exec执行./a.out,并把各个环境变量存到char *envp[]里面去。其实这候,子进程调用的就是上一次我们所说的那个int execve( path , argv , envp )。我们这个程序是在bash或是csh什么上进行的。所以这回你相信我们上次那个自制的shell原理和那些非常牛的bash,csh是一样一样的了吧。所以我们也可以自豪地说:有什么的啊,我们的自行车不就是比宝马少俩轮吗?在轮子都是圆的这方面,原理是和宝马一样的。呵呵,想宝马想疯了。
这回我们给我们的shell加点功能,让它能够带上参数。
- #include <stdio.h>
- #include <string.h>
- void getarg( char *argv[] , char *p );
- int main()
- {
- static char prompt[64]="> ";
- char command[256], *argv[256], *p;
- int st;
- fprintf( stderr , "%s" , prompt );
- while( (p=gets(command))!=NULL )
- {
- getarg( argv , p );
- if( fork()==0 )
- {
- execv(argv[0],argv);
- }
- else
- {
- wait( &st );
- fprintf( stderr , "%s" , prompt);
- }
- }
- return 0;
- }
- void getarg( char *argv[] , char *buf )
- {
- int i = 1;
- argv[0] = strtok(buf," ");
- while((argv[i] = strtok(NULL," ")) != NULL)
- i++;
- }
复制代码
这回编译再试试看看是不是可以带参数了。
这个程序我不给注释了,参照上次那个程序相信大家能看懂吧。说一下里面的一个新函数strtok()
- #include <string.h>
- char *strtok(char *str, const char *delim);
复制代码
作用是将文字列str,按标记delim分段,delim可以是多个字符。使用方法:第一次调用时第一个参数是str本身,以后在调用第一个参数设成NULL。返回值就是分割后的每段段首的地址指针。举个例子,
- #include <stdio.h>
- #include <string.h>
- int main(void)
- {
- char str[] = "ABCD ef.1234.G";
- char *tp;
- tp = strtok( str, " ." ); //分段符设为空格和点
- puts( tp );
- while ( tp != NULL ) {
- tp = strtok( NULL," ." );
- if ( tp != NULL ) puts( tp );
- }
-
- return 0
- }
复制代码 ;
运行结果:
怎么样?一目了然,不用再多说明了吧。
好,我们的shell就先到这里了,毕竟我们为了入门嘛。我只是起了一个头,希望有兴趣的朋友自己可以在机器想些其它的有趣功能编着玩玩。当年我记得我们还做过,自动检查命令path的,可查询命令历史纪录的,显示子进程号的等等。“自行车”也做得像模像样的,可惜毕业时觉得也没什么用,就都留在学校机房的solaris里了,现在估计早被人删了。今天就说这么多,下次我准备说说关于进程状态。之后就开始说第二部分文件系统。
[ 本帖最后由 naker 于 2006-11-7 12:24 编辑 ] |
|