使用自动配置脚本:用C与脚本的混合编程来处理配置文件




  在上写、做网管或多或少都会几种脚本脚本语言灵活变量类型、强大正则表达式处理能力再加上系统本身管道、重定向以及丰富命令行工具让你编程起来游刃有余而C语言固然有种种优势但不可否认很多场合下用脚本语言更为方便比如我们将举例介绍说明对配置文件处理
  
  先看看我们举例任务:
  
  假设我们有个用c写它有个配置文件 user.conf保存了些用户信息user.conf定义如下:
  1)、以 # 开头行为注释行不做处理
  2)、允许空行
  3)、如果不是1和2那么就是有效数据格式如下
  # user.conf: configure file for user
  # username age sex country
  tom 20 male us
  chen 22 female cn
  
  每列分为4个字段字段的间用个或多个空白(空格或者制表符)隔开字段依次是 姓名、年龄、性别、国家我们c要完成对 user.conf添加、删除、编辑、查询
  
  这样个简单任务用c处理起来不算复杂不过也是要花点功夫而如果用脚本语言来做却很简单能不能在c中脚本来完成任务了?
  
  Awk是linux上种脚本语言长处在于处理有定格式规则文件例如咱们user.conf有关 awk 资料有很多oreilly公司出了专门 awk 编程书籍网上也是可以到你也可以直接 man awk看看
  
  我们先看看如何用 shell 结合 awk来完成上述任务:
  
  1) 添加条记录
  
  例如要添加 jack 18 male us 这样条记录可以简单用重定向功能
  Echo –e “jack 18 male us” >> user.conf
  现在这条记录被添加到 user.conf末尾了
  
  2) 删除条记录
  
  例如现在要删除用户 chen 信息
  cat user.conf | awk ‘!/^chen[[:blank:]]+/ {pr}’ > tmp.conf; mv –f tmp.conf user.conf
  
  3)、编辑条记录
  
  现在想把 tom性别改为 female
  cat user.conf | awk ‘{($0 ~ /^tom[[:blank:]]+/) pr $1 $2 female $3; pr}’
  
  通过 system这个我们就可以在 c 中以上脚本完成任务了
  
  但是system 用起来还是觉得不爽不足是只能执行脚本却无法获得脚本输出数据而这通常是我们进步处理数据来源(在shell和perl中可以通过反引号( `` )来取得命令输出结果) 个解决办法是把输出结果重定向到个临时文件中然后在c中读取文件获取数据最后当然还要删除这个文件不过这个思路方法总是让人觉得有点点不爽如果能直接把脚本执行中输出数据输到我们缓冲区来就更好了
  
  我写了个小叫 my_system通过管道以及重定向实现了以上想法
  
  原型如下:
  
   my_system(const char* pCmd, char* pResult, size);
  
  输出数据被保存到 pResult所指向缓冲区中缓冲区大小为 size最多可以保存 size-1数据实现放在本文最后
  
  有了这个以后在 c中脚本就更方便了我们可以通过它来实现对 user.conf查询
  
  4)、查询个记录
  
  例如我们要获取 tom 性别
  可以用脚本这样来实现:
  
  cat user.conf | awk ‘/^tom[[:blank:]]+/ {pr $3}’
  
  脚本执行结果是 tom性别 male被输出到屏幕上
  
  在我们 c如此my_system
  
  char buf[101];
  my_system(“cat user.conf | awk ‘/^tom[[:blank:]]+/ {pr $3}’”, buf, 101);
  
  完以后buf中数据就是 “male”了如何样还算方便吧?
  
  以上只是用结合脚本完成了个比较简单任务所以我没有把这些脚本单独形成脚本文件如果你善于使用 perl、shell、awk那么可以写出更强大脚本文件来处理更复杂问题然后通过类似 my_system( )思路方法在 c/c等其它语言中取得脚本输出结果实现有趣“混合编程”
  希望你能从中得到乐趣!
  
  #
  #
  #
  #
  #
   my_system(const char* pCmd, char* pResult, size)
  {
   fd[2];
   pid;
   count;
   left;
  char* p = 0;
   maxlen = size – 1;
  mem(pResult, 0, size);
  (pipe(fd))
  {
  prf("pipe errorn");
   –1;
  }
  ((pid = fork) 0)
  {// chile process
   fd2[2];
  (pipe(fd2))
  {
  prf("pipe2 errorn");
   –1;
  }
  close(1);
  dup2(fd2[1],1);
  close(fd[0]);
  close(fd2[1]);
  system(pCmd);
  read(fd2[0], pResult, maxlen);
  pResult[strlen(pResult)-1] = 0;
  write(fd[1], pResult, strlen(pResult));
  close(fd2[0]);
  exit(0);
  }
  // parent process
  close(fd[1]);
  p = pResult;
  left = maxlen;
  while((count = read(fd[0], p, left))) {
  p count;
  left -= count;
  (left 0)
  ;
  }
  close(fd[0]);
   0;
  }
  
   (void)
  {
  char result[1025];
  my_system("/sbin/config", result, 1025);
  prf("the result isnn%sn", result);
   0;
  }
Tags:  shell脚本编程 脚本编程 自动配置脚本 使用自动配置脚本

延伸阅读

最新评论

发表评论