Linux下自定义命令行实用程序及命令的man手册的编写

2024-02-19 22:18

本文主要是介绍Linux下自定义命令行实用程序及命令的man手册的编写,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 

     这个命令行程序的功能是解决在Linux下编写C代码的时候,快速创建.h和.c文件的模板,为了来规范代码。实现这个程序的主要目的是我想熟悉一下命令行程序的编写以及如何自定义自己写的命令的man手册.

这个自定义的命令为create,下面为实现过程:

 

//create.c

/**********************************************************    
FileName : create.c 
FileFunc : Linux下实现.c和.h文件模板    
Version  : V0.1     
Author   : Sunrier     
Date     : 2012-06-28 
Descp    : Linux下实现命令行实用程序   
*************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
void GetLocalTime( char *pOutTime );
unsigned char createfile( unsigned char ucFileFlag,char *pFilename );
void StrToUpper( char *pcStr );
void write_h( FILE *fp ,char *pFileName,char *pAliasName);
void write_c( FILE *fp,char *pFileName );
void GetLocalTime( char *pOutTime )  
{  
time_t t;  
struct tm tm1;  
t = time(NULL);  
memcpy(&tm1,localtime(&t),sizeof(struct tm));  
sprintf(pOutTime,"%04d-%02d-%02d %02d:%02d:%02d",tm1.tm_year+1900,tm1.tm_mon+1,tm1.tm_mday,tm1.tm_hour,tm1.tm_min,tm1.tm_sec);  
/*YYYYMMDDHHMMSS(年月日时分秒)   */
}  
void StrToUpper( char *pcStr )
{
while( '\0'!=*pcStr )
{
if( islower(*pcStr) )
*pcStr -= 32; 
++pcStr;
}
}
int main( int argc,char *argv[] )  
{
unsigned char ucRetCode = 1;
if( 2==argc )  
{  
if( 0==memcmp(argv[1],"--help",strlen(argv[1])) )
{
fprintf(stderr,"用法:create 选项... 文件... \n");
fprintf(stderr,"根据<选项>参数的设置来选择创建指定的<文件>是.h文件还是.c文件。\n");
fprintf(stderr,"\n<选项>	<文件> 参数的设置\n");
fprintf(stderr,"-h	filename		创建名为filename.h文件\n");
fprintf(stderr,"-c	filename		创建名为filename.c文件\n");
fprintf(stderr,"--help				显示此帮助信息并退出\n");
fprintf(stderr,"--version			输出版本信息并退出\n");
fprintf(stderr,"\n如遇到问题,请向 <sunrier@gmail.com> 报告错误。\n");
}
else if( 0==memcmp(argv[1],"--version",strlen(argv[1])) )
{
fprintf(stderr,"create (free code) 1.01\n");
fprintf(stderr,"这是自由软件,相互交流学习可以加入QQ群:80060765 \n");
fprintf(stderr,"\n");
fprintf(stderr,"由 Sunrier 编写\n");
}
else
{
fprintf(stderr,"%s:无效选项\"%s\"   \n",argv[0],argv[1]);
fprintf(stderr,"请尝试执行 \"create --help\" 来获取更多的信息. \n");
}			  
exit (1);  
}  
if( 3!=argc )
{
fprintf(stderr,"%s:无效选项  \n",argv[0]);
fprintf(stderr,"请尝试执行 \"create --help\" 来获取更多的信息. \n");
exit (1);
}
if( '-'==*argv[1])
{	
if( 0==memcmp(argv[1],"-h",strlen(argv[1])) )
{	
ucRetCode = createfile(0,argv[2]);
}	
else if( 0==memcmp(argv[1],"-c",strlen(argv[1])) )
{	
ucRetCode = createfile(1,argv[2]);          		
}	
else
{
fprintf(stderr,"%s:无效选项\"%s\"  \"%s\" \n",argv[0],argv[1],argv[2]);
fprintf(stderr,"请尝试执行 \"create --help\" 来获取更多的信息. \n"); 
exit(1);
}	
}
else
{
fprintf(stderr,"%s:无效选项\"%s\"  \"%s\" \n",argv[0],argv[1],argv[2]);
fprintf(stderr,"请尝试执行 \"create --help\" 来获取更多的信息. \n"); 
exit(1);
}	
return ucRetCode;
}
unsigned char createfile(unsigned char ucFileFlag,char *pFilename)
{
unsigned char ucRetCode = 1;
char szFileName[30];
char szAliasName[30];
FILE *fp = NULL;
unsigned int uiI;
if( strlen(pFilename)>27 )
{
fprintf(stderr,"%s:创建文件失败,文件名长度太长!\n",pFilename);
return 1;
}	 
memset(szFileName,0,sizeof(szFileName));
if( !ucFileFlag )
{	
sprintf(szFileName,"%s.h",pFilename);
}
else
{
sprintf(szFileName,"%s.c",pFilename);
}	
memset(szAliasName,0,sizeof(szAliasName));
sprintf(szAliasName,"%s",pFilename);
StrToUpper(szAliasName);
fp = fopen(szFileName,"r");
if( NULL!=fp )
{
fclose(fp);
fprintf(stderr,"%s:创建文件失败,你指定的文件名当前目录下已经存在!\n",pFilename);
return 1;
}	
fp = NULL;
fp = fopen(szFileName,"a");
if( NULL==fp )
{
fprintf(stderr,"%s:创建文件失败!\n",pFilename);
return 1;
}
if( !ucFileFlag )
{
write_h(fp,szFileName,szAliasName);
}
else
{
write_c(fp,szFileName);
}	
fclose(fp);
return 0;
}
void write_h( FILE *fp ,char *pFileName,char *pAliasName )
{
char szTime[30];
memset(szTime,0,sizeof(szTime));
GetLocalTime(szTime);
fprintf(fp,"/*************************************************************\n");
fprintf(fp,"    FileName : %s \n",pFileName);
fprintf(fp,"    FileFunc : 定义头文件  \n");
fprintf(fp,"    Version  : V0.1  \n");
fprintf(fp,"    Author   : Sunrier  \n");
fprintf(fp,"    Date     : %s \n",szTime);
fprintf(fp,"    Descp    : Linux下头文件 \n");
fprintf(fp,"*************************************************************/\n");
fprintf(fp,"#ifndef   __%s_H__\n",pAliasName);
fprintf(fp,"#define   __%s_H__\n",pAliasName);
fprintf(fp,"\n");
fprintf(fp,"#ifdef __cplusplus\n");
fprintf(fp,"extern \"C\" {\n");
fprintf(fp,"#endif\n");
fprintf(fp,"\n\n\n\n");
fprintf(fp,"#ifdef __cplusplus\n");
fprintf(fp,"}\n");
fprintf(fp,"#endif\n");
fprintf(fp,"\n");
fprintf(fp,"#endif\n");			
}
void write_c( FILE *fp,char *pFileName )
{
char szTime[30];
memset(szTime,0,sizeof(szTime));
GetLocalTime(szTime);
fprintf(fp,"/*************************************************************\n");
fprintf(fp,"    FileName : %s \n",pFileName);
fprintf(fp,"    FileFunc : 定义实现文件  \n");
fprintf(fp,"    Version  : V0.1  \n");
fprintf(fp,"    Author   : Sunrier  \n");
fprintf(fp,"    Date     : %s \n",szTime);
fprintf(fp,"    Descp    : Linux下实现文件 \n");
fprintf(fp,"*************************************************************/\n");
fprintf(fp,"#include <stdio.h>\n");
fprintf(fp,"\n");
fprintf(fp,"int main(int argc,char *argv[])\n");
fprintf(fp,"{\n");
fprintf(fp,"\n\n");
fprintf(fp,"	return 0;\n");
fprintf(fp,"}\n");
fprintf(fp,"\n");
}


 

//makefile

#makefile
OBJS = create  
all:$(OBJS)  
CFLAGS = -O -w -ansi     
#CFLAGS = -O -Wall -ansi    
CC = gcc $(CFLAGS)
create:create.c  
@$(CC) -o $@ $? 
@gzip -c create.1 > create.1.gz 
@mv create.1.gz /usr/share/man/man1
#gzip压缩成.gz 文件
#gzip不加参数时,默认压缩文件时,不保存原来的文件;
#如gzip create.1 结果只有压缩文件create.1.gz,原文件create.1没有了.
clean:
@ls | grep -v ^makefile$$ | grep -v [.]c$$ | grep -v [.]h$$ | grep -v [.]1$$ | grep -v [.]txt$$ | xargs rm -rf
#makefile 


 

 

下面为实现自定义的create命令的man手册:

//create.1

.\"表示:行首注释  而\":表示在行中的注释
.\":create命令程序手册页的实例
.TH CREATE 1 "2012-06-28" "create 1.01" "User Commands"
.\"CREATE:表示标题
.\"1:表示此命令出现在手册页的第几部分,范围为1-8的数字,和定义这个文件名小数点后的数字一致
.\""2012-06-28":表示"2012-06-28"显示在整个页的下中
.\""create 1.01":表示"create 1.01"显示在整个页的左下
.\""User Commands":表示"User Commands"显示在整个页的上中
.\".TH在文件的开始,主要说明标题
.SH NAME
.\"说明名称
.\".SH从行首开始,靠左边,宽体
\fBcreate\fR \- A simple demonstration application creates a file that head file or c file .
.\"-:表示为\-
.SH SYNOPSIS
.\"说明语法格式
.B create
.\".B:表示宽体,如果本行没有文字,则.B标签的下一行为宽体
\-OPTION... FILE...
.SH DESCRIPTION
.\"说明本命令或程序等的相关描述
This manual page document is from Sunrier . \fBcreate\fR is a common application for create a new file that .c or .h file .
.\"\fB文字\fR:表示将该文字设置成宽体
.\"\fI文字\fR:表示将文字加下划线
.\".:表示为\&.
.SH OPTIONS
.\"说明参数选项设置
It will decide to create a .h file or .c file 
.sp
.\".sp:表示空行
.B \-h
It will create a new head file 
.sp
.B \-c
It will create a new c file
.sp
.B \-\-help
display this help and exit
.sp
.B \-\-version
output version information and exit
.SH COPYRIGHT
.\":版权声明
\fBcreate\fR is Copyright Sunrier .This program is free  software ,you can redistribute it or modify it under the GNU General Public License as published by the free software foundation .
.SH SEE ALSO
.\":其他参考
This program is a template of c and h files to quickly create .
.SH REPORTING BUGS
.\":漏洞说明
.TP 0
.\".TP n:表示TP标签下的第2行开始缩进n个字符(在第1行超过n字符的前提下) n默认值为7
.\".TP 0:表示Report bugs to <sunrier@gmail.com> .这一句缩进0个字符,这句即为了实现换行的作用
There probably are some,but I don't know that what they are yet.
Report bugs to <sunrier@gmail.com> .
.SH AUTHOR
.\":文档编写作者
Written by Sunrier .
.\"看显示创建man手册命令的结果groff -Tascii -man create.1(注:此时不会创建任务文件,只是看下显示效果)
.\"gzip create.1 把create.1压缩成.gz 文件,会创建一个create.1.gz的文件,而create.1文件会在gzip执行完后删除
.\"如果想保留原文件可以这样用:gzip -c create.1 > create.1.gz
.\"把文件create.1.gz放到/usr/share/man/man1下就可以完成create命令的man手册了
.\"当执行man create后还会在在/var/cache/man/cat1/create.1.bz2创建一个create.1.bz2压缩文件


 

[root@localhost Sunrier]# ls
create.1  create.c  makefile
[root@localhost Sunrier]# make
[root@localhost Sunrier]#ls
create  create.1  create.c  makefile
[root@localhost Sunrier]# ./create -h test
[root@localhost Sunrier]# ls
create  create.1  create.c  makefile  test.h
[root@localhost Sunrier]#./create -c test
[root@localhost Sunrier]# ls
create  create.1  create.c  makefile  test.c  test.h
[root@localhost Sunrier]# man create
[root@localhost Sunrier]#

 

 

 

注:为了像常用的命令一样使用,可以把create放到可执行bin路径下如/usr/bin,可以用echo $PATH看下当前的系统默认执行路径有哪些!

这篇关于Linux下自定义命令行实用程序及命令的man手册的编写的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/726144

相关文章

Redis 的 SUBSCRIBE命令详解

《Redis的SUBSCRIBE命令详解》Redis的SUBSCRIBE命令用于订阅一个或多个频道,以便接收发送到这些频道的消息,本文给大家介绍Redis的SUBSCRIBE命令,感兴趣的朋友跟随... 目录基本语法工作原理示例消息格式相关命令python 示例Redis 的 SUBSCRIBE 命令用于订

防止Linux rm命令误操作的多场景防护方案与实践

《防止Linuxrm命令误操作的多场景防护方案与实践》在Linux系统中,rm命令是删除文件和目录的高效工具,但一旦误操作,如执行rm-rf/或rm-rf/*,极易导致系统数据灾难,本文针对不同场景... 目录引言理解 rm 命令及误操作风险rm 命令基础常见误操作案例防护方案使用 rm编程 别名及安全删除

Linux下MySQL数据库定时备份脚本与Crontab配置教学

《Linux下MySQL数据库定时备份脚本与Crontab配置教学》在生产环境中,数据库是核心资产之一,定期备份数据库可以有效防止意外数据丢失,本文将分享一份MySQL定时备份脚本,并讲解如何通过cr... 目录备份脚本详解脚本功能说明授权与可执行权限使用 Crontab 定时执行编辑 Crontab添加定

Java使用jar命令配置服务器端口的完整指南

《Java使用jar命令配置服务器端口的完整指南》本文将详细介绍如何使用java-jar命令启动应用,并重点讲解如何配置服务器端口,同时提供一个实用的Web工具来简化这一过程,希望对大家有所帮助... 目录1. Java Jar文件简介1.1 什么是Jar文件1.2 创建可执行Jar文件2. 使用java

Vite 打包目录结构自定义配置小结

《Vite打包目录结构自定义配置小结》在Vite工程开发中,默认打包后的dist目录资源常集中在asset目录下,不利于资源管理,本文基于Rollup配置原理,本文就来介绍一下通过Vite配置自定义... 目录一、实现原理二、具体配置步骤1. 基础配置文件2. 配置说明(1)js 资源分离(2)非 JS 资

使用docker搭建嵌入式Linux开发环境

《使用docker搭建嵌入式Linux开发环境》本文主要介绍了使用docker搭建嵌入式Linux开发环境,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录1、前言2、安装docker3、编写容器管理脚本4、创建容器1、前言在日常开发全志、rk等不同

linux系统上安装JDK8全过程

《linux系统上安装JDK8全过程》文章介绍安装JDK的必要性及Linux下JDK8的安装步骤,包括卸载旧版本、下载解压、配置环境变量等,强调开发需JDK,运行可选JRE,现JDK已集成JRE... 目录为什么要安装jdk?1.查看linux系统是否有自带的jdk:2.下载jdk压缩包2.解压3.配置环境

Linux搭建ftp服务器的步骤

《Linux搭建ftp服务器的步骤》本文给大家分享Linux搭建ftp服务器的步骤,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录ftp搭建1:下载vsftpd工具2:下载客户端工具3:进入配置文件目录vsftpd.conf配置文件4:

Linux实现查看某一端口是否开放

《Linux实现查看某一端口是否开放》文章介绍了三种检查端口6379是否开放的方法:通过lsof查看进程占用,用netstat区分TCP/UDP监听状态,以及用telnet测试远程连接可达性... 目录1、使用lsof 命令来查看端口是否开放2、使用netstat 命令来查看端口是否开放3、使用telnet

Linux系统管理与进程任务管理方式

《Linux系统管理与进程任务管理方式》本文系统讲解Linux管理核心技能,涵盖引导流程、服务控制(Systemd与GRUB2)、进程管理(前台/后台运行、工具使用)、计划任务(at/cron)及常用... 目录引言一、linux系统引导过程与服务控制1.1 系统引导的五个关键阶段1.2 GRUB2的进化优