`
shangjava
  • 浏览: 1229146 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

如何编写一个完整的Linux命令

 
阅读更多
作者:gzshun. 原创作品,转载请标明出处!
来源:http://blog.csdn.net/gzshun


一个完整的Linux命令需要有以下几个重要的部分组成:
1.使用方法
2.命令行参数
3.移植性

1.使用方法

在每个命令当中,都需要提供一个usage函数,当然名称不一定要用这个。看了很多开源软件,几乎都是使用usage命名。usage一般是在用户输入不规则的命令行参数才调用的,也就是打印出详细的使用方法。比如我以下随便给一个Linux命令传入一个没有被提供的参数,执行结果是这样:


这里每一个命令行选项都代表一个功能,有些选项后面可以跟着参数,比如e2fsck中[-b superblock] [-B blocksize]等等。

2.命令行参数
在第1点,已经贴出usage的打印信息,上面那些-p,-n等等的就是命令行参数,本文也是重点说明这个命令行参数的使用。在执行一个Linux命令的时候,可能只需要增加一个选项(比如: cp -a ...),也可能需要在一个选项后面跟一个参数(比如: e2fsck -C0 或者 e2fsck -C 0),其实"e2fsck -C0"与"e2fsck -C 0"是等价的。这里分析命令行参数的功臣归功于"getopt"函数,getopt()用来分析参数选项,具体可以参考:(UNIX环境高级编程 第21章 与网络打印机通信 p619),当然在UNIX环境高级编程这本书里面,这个函数只是稍微带过,没有详细讲解。

3.移植性
通常一个开源软件的移植性都是考虑得相当周全,在Linux平台下的开源软件,经常被移植到不同的平台,这就必须考虑到不同平台的可移植性。当然我对软件的可移植性这方面的知识欠缺,有待改进,本文不对移植性解释。

一、为什么要写一个完整的Linux命令?
在Linux的平台下,很多重要的功能都是在命令行实现的,也许我们平时也需要自己动手实现一个自己的程序,当然要一个相对比较有质量的。这里就会涉及到一个Linux命令的设计,第一步肯定是要分析命令行参数选项。
自己动手写一个完整的Linux命令,这里的标题写得有点吹,本来我打算写一个相对比较完整的cp命令,但考虑下流程,处理的东西很多,包括文件,目录的属性,还有递归,去掉上班时间,我晚上时间有限,就不想写,那些也都是比较容易的问题。cp这一个命令对于Linux的用户再熟悉不过了,网上也提供很多程序员自己写的cp命令,但我觉得都不完整,因为网上有些cp程序都是直接读取源文件写到目标文件,仅仅写了一个while循环,这样根本就谈不上一个完整的Linux命令。我们平时使用的cp命令,源码有1063行,包括注释,一个简单的功能,其实涉及到很多Linux平台下的特性,需要考虑到文件属性,目录属性,权限,用户和组ID,修改时间,状态修改时间等等。

二、Linux命令的一些例子?
举个例子:
复制一个src目录到dst目录的命令,这里可能会有3种写法:
1.cp -a src dst
2.cp src -a dst
3.cp src dst -a
这3条命令都可以达到将src目录拷贝到dst目录的效果,这里就是命令行参数的功劳了,这也就是getopt函数的好处。如果写一个命令,没有使用getopt函数来处理命令行参数,那将处理不了这三种命令行参数的写法。

例子:
检测磁盘的一个工具e2fsck,该函数有一个选项是[-C fd],后面跟一个参数,这个选项是选择一个不同的进度打印消息。这里同样有几种写法:
1.e2fsck /dev/sda1 -C0
2.e2fsck /dev/sda1 -C 0
在命令行参数,也支持这样的形式,选项可以跟选项后面跟的参数写在一起,也可以分离,但必须紧跟在选项后面。

当然本文也写不出完整的Linux命令,水平有限,只是写出命令行参数的解析部分。

例子:这里是一个简单的测试程序,将程序的参数打印出来;
./cp aa bb cc dd ee -l -d

//这里直接将main函数的argv二位数组打印出来
argv[0]=./cp
argv[1]=aa
argv[2]=bb
argv[3]=cc
argv[4]=dd
argv[5]=ee
argv[6]=-l
argv[7]=-d
//这里是调用完getopt后argv的变化结果
argv[0]=./cp
argv[1]=-l
argv[2]=-d
argv[3]=aa
argv[4]=bb
argv[5]=cc
argv[6]=dd
argv[7]=ee

从这个例子,可以得到以下结果:
1.getopt函数具有排序功能;
2.argv是一个可以修改的二维数组;

三、getopt的使用?
1.排序功能
getopt会先将命令行参数进行排序,选项在前,剩下的参数在后面,第0个参数始终是程序自己;
排序规则:
只将有"-"选项与该选项的参数提到程序的后面,剩下的一些都放在最后面,但原有的参数顺序没有更改,这里有点拗口,直接看例子:
cp -a -r src1/ src2/ src3/ dst/
这条命令的任务是将src1,src2,src3目录拷贝到dst目录下,src1,src2,src3参数必须在dst参数的前面,所以getopt不会破坏原来的参数顺序,例子:
cp src1/ src2/ -a src3/ -r dst/
经过getopt的处理,argv数组将会变成cp -a -r src1/ src2/ src3/ dst/,-a和-r原有的顺序也保持不变,-a在前,-r在后。

2.参数解析
有些命令的选项后面会跟着一个参数,可以是数字,也可以是字母,或字符串,均可。例子:
e2fsck /dev/sda1 -C0,这里-C选项的参数是0。也可以写成e2fsck /dev/sda1 -C 0,跟前面那句命令等价。

3.getopt的具体用法
讲这么废话,终于到了getopt了。
getopt函数声明在unistd.h头文件中,有以下一些相关函数和全局变量:


这里写个例子来说明(虚拟的): mycp -a -b hello -c123 src dst
char *optarg: -b的optarg是hello,-c的optarg是123,optarg就是选项后面跟着的参数;
int optind : 下一个要处理的参数的下标(argv);
int opterr : 如果将opterr设为0,则getopt不输出错误信息,否则报错,形如(e2fsck: invalid option -- 'x')
int optopt : 当命令行选项字符不包括在optstring中或者选项缺少必要的参数时,该选项存储在optopt中
int getopt(int argc, char * const argv[], const char *optstring) : optstring看起来比较不清楚,待会儿看代码。该函数执行完或者失败返回-1.

源程序:


程序的执行结果1:
这里故意打乱顺序,为了更清楚的查看getopt的使用方法


程序的执行结果2:
使用-h选项来打印命令的使用方法


个人喜欢vi的颜色配置,贴一张出来看看,挺鲜艳:



本人不才,以上可能存在错误的认识。
由于最近写了3个Linux命令,在CSDN博客总结一下收获,虽然这种程序是菜鸟级的,但我把它记录下来,等我下次要查看,一目了然,这就是效率。希望大牛不要鄙视,我写这种无聊的程序,只是一个学习态度罢了。

分享到:
评论

相关推荐

    LinuxC编写的tracert命令

    LinuxC编写的tracert命令LinuxC编写的tracert命令LinuxC编写的tracert命令LinuxC编写的tracert命令LinuxC编写的tracert命令LinuxC编写的tracert命令LinuxC编写的tracert命令LinuxC编写的tracert命令LinuxC编写的...

    LinuxC编写的ping命令

    LinuxC编写的ping命令LinuxC编写的ping命令LinuxC编写的ping命令LinuxC编写的ping命令LinuxC编写的ping命令LinuxC编写的ping命令LinuxC编写的ping命令LinuxC编写的ping命令LinuxC编写的ping命令LinuxC编写的ping命令...

    Linux命令模板 licote 1.1.0

    用于快速编写一个linux环境的命令程序,当然如果你愿意,你可以用于任何程序中;Licote的主要任务就是帮助你解析linux环境下的常用命令选项,让你快速的编写命令程序的同时,为用户提供灵活而强大的使用方法; ...

    jenkins 执行远程linux命令

    SSH Plugin是Jenkins的一个插件,它提供了一种简单的方式来执行远程Linux命令。安装步骤如下: 1. **打开Jenkins管理界面**:登录到您的Jenkins实例,在左侧导航栏中选择“系统管理”,然后点击“管理插件”。 2. *...

    Linux命令模板 licote 1.2.2

    用于快速编写一个linux环境的命令程序,当然如果你愿意,你可以用于任何程序中;Licote的主要任务就是帮助你解析linux环境下的常用命令选项,让你快速的编写命令程序的同时,为用户提供灵活而强大的使用方法; ...

    Java语言编写的Linux简单命令解释器

    本项目专注于使用Java语言构建一个针对Linux操作系统的简单命令解释器,这为理解这两者的结合提供了一个实用的学习平台。以下是关于这个项目的详细知识点: 1. **Java语言**:Java是一种跨平台的面向对象的编程语言...

    Linux命令模板 licote 1.3.2

    用于快速编写一个linux环境的命令程序,Licote的主要任务是帮助你解析linux环境下的常用命令选项,让你快速编写命令程序的同时,为用户提供灵活而强大的使用方法;通过Licote框架你可以开发类似tcpdump,date等选项...

    Linux命令大全手册中文版

    以上仅是Linux命令海洋中的一部分,通过"Linux命令大全手册中文版",你可以深入了解每一个命令的具体用法、参数和实例,进一步提升你的Linux操作技能。CHM格式的文档使得查询变得轻松,无论你是初学者还是经验丰富的...

    Linux命令解释与示例

    总结,Linux命令是Linux系统操作的核心,通过不断实践和学习,你可以成为一个高效的Linux用户。记住,每一个命令都是你通向更深层次Linux世界的一把钥匙。不断探索,你会发现更多有趣和实用的功能。

    linux 命令 编程接口

    Linux命令编程接口不仅包括了用户直接输入的命令,还包括了开发者可以利用的C语言编程接口,使得程序员能创建自己的系统工具和服务。本主题将深入探讨这些知识点。 首先,Linux命令是操作系统提供的一系列可执行...

    Linux命令大全CHM,支持查询

    "Linux命令大全CHM,支持查询"提供了这样一个资源,它是一个以CHM(Microsoft HTML Help)格式编写的Linux命令参考手册,方便用户进行快速查询。 CHM文件是一种基于HTML的帮助文档格式,它将多个网页文件、图像和...

    linux 用法 │的用法 管道,将一个程序命令的输出作为另一个程序名称的输入

    在Linux操作系统中,管道符号“|”是一种非常重要的功能特性,它能够将一个命令的输出直接作为下一个命令的输入,从而实现高效的命令组合与数据处理流程。这种机制极大地提升了用户在进行复杂操作时的效率与灵活性。...

    java通过代码登录远程linux服务器并执行linux命令源码以及jar包

    结合以上代码,你可以实现一个完整的Java程序,通过输入Linux服务器的用户名、密码、主机地址和要执行的命令,远程登录并执行命令。如果你有密钥对认证的需求,可以使用`session.setUserInfo(UserInfo)`接口并实现其...

    Linux命令大全搜索工具

    这个“Linux命令大全搜索工具”提供了丰富的资源,帮助用户快速查找和学习各种Linux命令。 1. **Linux命令基础** Linux命令行界面是通过输入指令与系统交互的方式,每个命令都有其特定的功能。例如,`ls`用于列出...

    linux-Linux命令大全内容包含Linux命令手册详解学习搜集

    本资源"Linux命令大全"包含了516个Linux命令的详细资料,对于学习和理解Linux操作系统至关重要。下面,我们将深入探讨这个资源中涉及的一些关键知识点。 1. **命令手册**: - 在Linux世界中,命令手册(man pages...

    linux命令大全chm版本是一款完整版的linux命令教程安装程序.zip

    这个压缩包包含了“Linux命令大全”教程的CHM文件,方便用户快速查找和学习Linux命令。 Linux是开源的操作系统,广泛应用于服务器、嵌入式设备和个人计算机。在Linux环境中,命令行接口(CLI)是进行系统管理、文件...

    linux命令学习chm文件

    3. **文本编辑器**:学习Linux命令时,掌握一个文本编辑器至关重要,如`nano`、`vi`(或其增强版`vim`)和`emacs`。特别是`vi/vim`,它是Linux环境下的标准编辑器,虽然上手难度稍高,但熟练掌握后效率极高。 4. **...

    linux命令api带详细参数解释

    本文将围绕“Linux命令API带详细参数解释”这一主题,深入探讨Linux命令及其参数,并以“Linux常用命令全集.CHM”为参考,为你提供一个全面的概述。 首先,Linux命令是操作系统中的一系列程序,通过终端输入,执行...

    Linux下Shell命令解释步骤程序实现

    第一个单词是命令的名称,而后面的则是命令参数。 查找文件 Shell 为每个用户提供了一组环境变量,这些变量定义在用户的 .login 文件中。其中 PATH 环境变量是一个有序的绝对路径列表,它指明了 Shell 应该在什么...

    Linux命令宝典大全

    Linux命令通常由一个或多个关键词组成,每个命令都有特定的参数和选项来扩展其功能。例如,`ls`命令用于列出目录内容,而`cd`则用于切换当前工作目录。 Linux命令宝典大全中可能涵盖了以下核心知识点: 1. **文件...

Global site tag (gtag.js) - Google Analytics