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

相关文章

SpringBoot全局异常拦截与自定义错误页面实现过程解读

《SpringBoot全局异常拦截与自定义错误页面实现过程解读》本文介绍了SpringBoot中全局异常拦截与自定义错误页面的实现方法,包括异常的分类、SpringBoot默认异常处理机制、全局异常拦... 目录一、引言二、Spring Boot异常处理基础2.1 异常的分类2.2 Spring Boot默

自定义注解SpringBoot防重复提交AOP方法详解

《自定义注解SpringBoot防重复提交AOP方法详解》该文章描述了一个防止重复提交的流程,通过HttpServletRequest对象获取请求信息,生成唯一标识,使用Redis分布式锁判断请求是否... 目录防重复提交流程引入依赖properties配置自定义注解切面Redis工具类controller

Linux内核定时器使用及说明

《Linux内核定时器使用及说明》文章详细介绍了Linux内核定时器的特性、核心数据结构、时间相关转换函数以及操作API,通过示例展示了如何编写和使用定时器,包括按键消抖的应用... 目录1.linux内核定时器特征2.Linux内核定时器核心数据结构3.Linux内核时间相关转换函数4.Linux内核定时

Linux镜像文件制作方式

《Linux镜像文件制作方式》本文介绍了Linux镜像文件制作的过程,包括确定磁盘空间布局、制作空白镜像文件、分区与格式化、复制引导分区和其他分区... 目录1.确定磁盘空间布局2.制作空白镜像文件3.分区与格式化1) 分区2) 格式化4.复制引导分区5.复制其它分区1) 挂载2) 复制bootfs分区3)

Redis 命令详解与实战案例

《Redis命令详解与实战案例》本文详细介绍了Redis的基础知识、核心数据结构与命令、高级功能与命令、最佳实践与性能优化,以及实战应用场景,通过实战案例,展示了如何使用Redis构建高性能应用系统... 目录Redis 命令详解与实战案例一、Redis 基础介绍二、Redis 核心数据结构与命令1. 字符

Linux服务器数据盘移除并重新挂载的全过程

《Linux服务器数据盘移除并重新挂载的全过程》:本文主要介绍在Linux服务器上移除并重新挂载数据盘的整个过程,分为三大步:卸载文件系统、分离磁盘和重新挂载,每一步都有详细的步骤和注意事项,确保... 目录引言第一步:卸载文件系统第二步:分离磁盘第三步:重新挂载引言在 linux 服务器上移除并重新挂p

Linux下屏幕亮度的调节方式

《Linux下屏幕亮度的调节方式》文章介绍了Linux下屏幕亮度调节的几种方法,包括图形界面、手动调节(使用ACPI内核模块)和外接显示屏调节,以及自动调节软件(CaliseRedshift和Reds... 目录1 概述2 手动调节http://www.chinasem.cn2.1 手动屏幕调节2.2 外接显

Linux(centos7)虚拟机没有IP问题及解决方案

《Linux(centos7)虚拟机没有IP问题及解决方案》文章介绍了在CentOS7中配置虚拟机网络并使用Xshell连接虚拟机的步骤,首先,检查并配置网卡ens33的ONBOOT属性为yes,然后... 目录输入查看ZFhrxIP命令:ip addr查看,没有虚拟机IP修改ens33配置文件重启网络Xh

kafka自定义分区器使用详解

《kafka自定义分区器使用详解》本文介绍了如何根据企业需求自定义Kafka分区器,只需实现Partitioner接口并重写partition()方法,示例中,包含cuihaida的数据发送到0号分区... 目录kafka自定义分区器假设现在有一个需求使用分区器的方法总结kafka自定义分区器根据企业需求

linux实现对.jar文件的配置文件进行修改

《linux实现对.jar文件的配置文件进行修改》文章讲述了如何使用Linux系统修改.jar文件的配置文件,包括进入文件夹、编辑文件、保存并退出编辑器,以及重新启动项目... 目录linux对.jar文件的配置文件进行修改第一步第二步 第三步第四步总结linux对.jar文件的配置文件进行修改第一步进