免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
1234下一页
最近访问板块 发新帖
查看: 7930 | 回复: 30
打印 上一主题 下一主题

[C] 用标准C实现shell功能 [复制链接]

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2003-05-07 18:48 |只看该作者 |倒序浏览
下面是代码,有兴趣的试试。


  1. #include <unistd.h>;
  2. #include <stdio.h>;
  3. #include <stdlib.h>;
  4. #include <sys/wait.h>;
  5. #include <string.h>;
  6. #include <errno.h>;

  7. #define SHELL_NAME "sh1"
  8. #define PROMPT_ENVIRONMENT_VARIABLE "PROMPT"

  9. char *prompt;

  10. int main(int argc, char **argv)
  11. {
  12.         char cmd[80];
  13.         int statval;
  14.   
  15.         /* Determine prompt value. */
  16.         if ((prompt = getenv(PROMPT_ENVIRONMENT_VARIABLE)) == NULL)
  17.                 prompt = SHELL_NAME ":";

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

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

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

  34.                 wait(&statval);
  35.                 if(WIFEXITED(statval))
  36.                 {
  37.                         if(WEXITSTATUS(statval))
  38.                         {
  39.                                 fprintf(stderr,
  40.                                         "%s: child exited with status %d.\n",
  41.                                         argv[0], WEXITSTATUS(statval));
  42.                         }
  43.                 } else {
  44.                         fprintf(stderr, "%s: child died unexpectedly.\n",
  45.                                 argv[0]);
  46.                 }
  47.         }
  48. }
复制代码

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
2 [报告]
发表于 2003-05-07 18:59 |只看该作者

用标准C实现shell功能

这是对上面代码做了改进以后的版本。



  1. #include <unistd.h>;
  2. #include <stdio.h>;
  3. #include <stdlib.h>;
  4. #include <sys/wait.h>;
  5. #include <errno.h>;

  6. char *parse_cmd(char *cmd, char **argarr, int *narg) {
  7.         enum states { S_START, S_IN_TOKEN, S_IN_QUOTES, S_SEMI };
  8.         int argc=0;                        // Arg count
  9.         int loop=1;                        // Loop control
  10.         enum states state = S_START;        // Current state.
  11.         int lastch;                        // Last character encountered.
  12.    
  13.         while (loop) {
  14.                 switch (state) {
  15.                 case S_START:
  16.                         if (*cmd == '"') {
  17.                                 *argarr++ = cmd + 1;
  18.                                 ++argc;
  19.                                 state = S_IN_QUOTES;
  20.                         }
  21.                         else if (*cmd == 0 || *cmd == ';')
  22.                                 loop = 0;
  23.                         else if (*cmd <= ' ')
  24.                                 *cmd = 0;
  25.                         else {
  26.                                 *argarr++ = cmd;
  27.                                 ++argc;
  28.                                 state = S_IN_TOKEN;
  29.                         }
  30.                         break;
  31.                 case S_IN_TOKEN:
  32.                         if (*cmd == 0 || *cmd == ';')
  33.                                 loop = 0;
  34.                         else if (*cmd <= ' ') {
  35.                                 *cmd=0;
  36.                                 state=S_START;
  37.                         }
  38.                         break;
  39.                 case S_IN_QUOTES:
  40.                         if (*cmd == 0)
  41.                                 loop = 0;
  42.                         else if (*cmd == '"') {
  43.                                 *cmd = 0;
  44.                                 state = S_START;
  45.                         }
  46.                 }
  47.                 cmd++;
  48.         }
  49.         *argarr = NULL;  /* store the NULL pointer */

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

  52.         lastch = cmd[-1];
  53.         cmd[-1] = 0;
  54.         return lastch == ';' ? cmd : NULL;
  55. }

  56. int main(int argc, char **argv) {
  57.         char cmd[80];                // Input command area.
  58.         char *source = NULL;        // Where commands to send to parser come from.
  59.         char *arg[21];                // Arg list.
  60.         int statval;                // Exec status value.
  61.         char *prompt="baby:";        // Command prompt, with default.
  62.         char *test_env;                // getenv return value.
  63.         int numargs;                // parse_cmd return value.
  64.   
  65.         if (test_env=getenv("BSPROMPT"))
  66.                 prompt=test_env;
  67.         while (1) {
  68.                 // See if we need to get a line of input.
  69.                 if(source == NULL) {
  70.                         printf(prompt);
  71.                         source = gets(cmd);
  72.                         if(source == NULL) exit(0);  // gets rtns NULL at EOF.
  73.                 }

  74.                 // Get the next command.
  75.                 source = parse_cmd(source, arg, &numargs);
  76.                 if (numargs == 0) continue;
  77.    
  78.                 // Exit command
  79.                 if (!strcmp(arg[0],"exit")) {
  80.                         if (numargs==1)
  81.                                 exit(0);
  82.                         if (numargs==2) {
  83.                                 if (sscanf(arg[1],"%d",&statval)!=1) {
  84.                                         fprintf(stderr,"%s: exit requires an "
  85.                                                 "integer status code\n",
  86.                                                 argv[0]);
  87.                                         continue;
  88.                                 }
  89.                                 exit(statval);
  90.                         }
  91.                         fprintf(stderr,"%s: exit takes one "
  92.                                 "optional parameter -integer status\n",
  93.                                 argv[0]);
  94.                         continue;
  95.                 }

  96.                 // Run it.
  97.                 if (fork()==0) {
  98.                         execvp(arg[0],arg);
  99.                         fprintf(stderr,"%s: EXEC of %s failed: %s\n",
  100.                                 argv[0],arg[0],strerror(errno));
  101.                         exit(1);
  102.                 }
  103.                 wait(&statval);
  104.                 if (WIFEXITED(statval)) {
  105.                         if (WEXITSTATUS(statval))
  106.                                 fprintf(stderr,"%s: child exited with "
  107.                                         "status %d\n", argv[0],
  108.                                         WEXITSTATUS(statval));
  109.                 } else {
  110.                         fprintf(stderr,"%s: child died unexpectedly\n",
  111.                                 argv[0]);
  112.                 }
  113.         }
  114. }
复制代码

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
3 [报告]
发表于 2003-05-22 19:25 |只看该作者

用标准C实现shell功能

up!有兴趣的请来分析!

论坛徽章:
0
4 [报告]
发表于 2003-05-23 07:06 |只看该作者

用标准C实现shell功能

太感谢了,找对组织了!

论坛徽章:
0
5 [报告]
发表于 2003-05-23 11:18 |只看该作者

用标准C实现shell功能

太难了,看不懂啊!

论坛徽章:
0
6 [报告]
发表于 2003-05-23 11:56 |只看该作者

用标准C实现shell功能

blue keyboard老大,第二个程序compile都过不了啊,请帮忙看看。

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
7 [报告]
发表于 2003-05-23 17:18 |只看该作者

用标准C实现shell功能

提示什么错误??

你的环境是??

论坛徽章:
0
8 [报告]
发表于 2003-05-29 10:05 |只看该作者

用标准C实现shell功能

我运行没问题
能简单讲一下吗?

论坛徽章:
0
9 [报告]
发表于 2003-05-30 08:41 |只看该作者

用标准C实现shell功能

也许是注释的问题。有的环境中,//不能被正确编译。要用/* */

论坛徽章:
0
10 [报告]
发表于 2003-05-30 09:19 |只看该作者

用标准C实现shell功能

[quote]原帖由 "acb"]也许是注释的问题。有的环境中,//不能被正确编译。要用/* */[/quote 发表:
     

相当正确!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP