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

相关文章

Linux中压缩、网络传输与系统监控工具的使用完整指南

《Linux中压缩、网络传输与系统监控工具的使用完整指南》在Linux系统管理中,压缩与传输工具是数据备份和远程协作的桥梁,而系统监控工具则是保障服务器稳定运行的眼睛,下面小编就来和大家详细介绍一下它... 目录引言一、压缩与解压:数据存储与传输的优化核心1. zip/unzip:通用压缩格式的便捷操作2.

Linux中SSH服务配置的全面指南

《Linux中SSH服务配置的全面指南》作为网络安全工程师,SSH(SecureShell)服务的安全配置是我们日常工作中不可忽视的重要环节,本文将从基础配置到高级安全加固,全面解析SSH服务的各项参... 目录概述基础配置详解端口与监听设置主机密钥配置认证机制强化禁用密码认证禁止root直接登录实现双因素

sqlite3 命令行工具使用指南

《sqlite3命令行工具使用指南》本文系统介绍sqlite3CLI的启动、数据库操作、元数据查询、数据导入导出及输出格式化命令,涵盖文件管理、备份恢复、性能统计等实用功能,并说明命令分类、SQL语... 目录一、启动与退出二、数据库与文件操作三、元数据查询四、数据操作与导入导出五、查询输出格式化六、实用功

在Linux终端中统计非二进制文件行数的实现方法

《在Linux终端中统计非二进制文件行数的实现方法》在Linux系统中,有时需要统计非二进制文件(如CSV、TXT文件)的行数,而不希望手动打开文件进行查看,例如,在处理大型日志文件、数据文件时,了解... 目录在linux终端中统计非二进制文件的行数技术背景实现步骤1. 使用wc命令2. 使用grep命令

postgresql数据库基本操作及命令详解

《postgresql数据库基本操作及命令详解》本文介绍了PostgreSQL数据库的基础操作,包括连接、创建、查看数据库,表的增删改查、索引管理、备份恢复及退出命令,适用于数据库管理和开发实践,感兴... 目录1. 连接 PostgreSQL 数据库2. 创建数据库3. 查看当前数据库4. 查看所有数据库

Java实现自定义table宽高的示例代码

《Java实现自定义table宽高的示例代码》在桌面应用、管理系统乃至报表工具中,表格(JTable)作为最常用的数据展示组件,不仅承载对数据的增删改查,还需要配合布局与视觉需求,而JavaSwing... 目录一、项目背景详细介绍二、项目需求详细介绍三、相关技术详细介绍四、实现思路详细介绍五、完整实现代码

一文详解Java Stream的sorted自定义排序

《一文详解JavaStream的sorted自定义排序》Javastream中的sorted方法是用于对流中的元素进行排序的方法,它可以接受一个comparator参数,用于指定排序规则,sorte... 目录一、sorted 操作的基础原理二、自定义排序的实现方式1. Comparator 接口的 Lam

Linux如何快速检查服务器的硬件配置和性能指标

《Linux如何快速检查服务器的硬件配置和性能指标》在运维和开发工作中,我们经常需要快速检查Linux服务器的硬件配置和性能指标,本文将以CentOS为例,介绍如何通过命令行快速获取这些关键信息,... 目录引言一、查询CPU核心数编程(几C?)1. 使用 nproc(最简单)2. 使用 lscpu(详细信

linux重启命令有哪些? 7个实用的Linux系统重启命令汇总

《linux重启命令有哪些?7个实用的Linux系统重启命令汇总》Linux系统提供了多种重启命令,常用的包括shutdown-r、reboot、init6等,不同命令适用于不同场景,本文将详细... 在管理和维护 linux 服务器时,完成系统更新、故障排查或日常维护后,重启系统往往是必不可少的步骤。本文

基于Linux的ffmpeg python的关键帧抽取

《基于Linux的ffmpegpython的关键帧抽取》本文主要介绍了基于Linux的ffmpegpython的关键帧抽取,实现以按帧或时间间隔抽取关键帧,文中通过示例代码介绍的非常详细,对大家的学... 目录1.FFmpeg的环境配置1) 创建一个虚拟环境envjavascript2) ffmpeg-py