Shell命令的选项和参数在本质上是什么?
很多 Shell 命令都是可以附带选项和参数的,不同的选项和参数也使得命令的功能细节有所差异。
Shell 命令附带参数的例子:
Shell 命令附带选项的例子:
有些命令的选项后面也可以附带参数:
你是否对这些形形色色的选项和参数感到好奇?你是否想知道它们在底层是如何实现的?你是否也想自己动手对它们进行解析?本节就来给你揭晓答案!
死磕这个细节并不是闲得无聊,它能帮助我们理解命令的真正含义。好了,废话不多说,让我们赶紧转入正题吧。
上节我们讲到,一个 Shell 内置命令就是一个内部的函数,一个外部命令就是一个应用程序。内置命令后面附带的所有数据(所有选项和参数)最终都以参数的形式传递给了函数,外部命令后面附带的所有数据(所有选项和参数)最终都以参数的形式传递给了应用程序。
也就是说,不管是内置命令还是外部命令,它后面附带的所有数据都会被“打包”成参数,这些参数有的传递给了函数,有的传递给了应用程序。
有编程经验的读者应该知道,C语言或者 C++ 程序的入口函数是
有了以上认知,我们就不用再区分函数和应用程序了,我们就认为:不管是内置命令还是外部命令,它后面附带的数据最终都以参数的形式传递给了函数。实现一个命令的一项重要工作就是解析传递给函数的参数。
注意,命令后面附带的数据并不是被合并在一起,作为一个参数传递给函数的;这些数据是由空格分隔的,它们被分隔成了几份,就会转换成几个参数。例如
并且,命令后面附带的数据都是“原汁原味”地传递给了函数,比如
至于在函数内部如何解析这些参数,对于外部命令来说那就是 C/C++ 程序员的工作了,这里不再过多赘述,只给出演示代码。
上节我给大家演示了一个 getsum 程序,本节依然使用该程序演示参数的解析,只是对代码进行了微调。
第 27~32 行将接收到的参数打印出来,以便读者更好地观察。
根据上节给出的办法就可以运行 getsum 命令:
Shell 命令附带参数的例子:
-
cd demo
命令表示进入当前目录下的 demo 目录,其中demo
就是 cd 命令的参数。 -
echo "123xyz"
命令表示输出字符串并换行,其中"123xyz"
就是 echo 命令的参数。
Shell 命令附带选项的例子:
ls -l
命令用来显示当前目录下的所有文件以及它们的详细信息,其中-l
就是 ls 命令的选项。echo -n "http://c.biancheng.net/shell/"
表示在输出字符串后不换行,其中-n
是 echo 命令的选项,"http://c.biancheng.net/shell/"
是 echo 命令的参数。有些命令的选项后面也可以附带参数:
-
getsum -s 1 -e 100
命令用来计算从 1 累加到 100 的和,其中-s
和-e
是 getsum 命令的选项,1
和100
分别是-s
和-e
选项的参数。 -
read -n 1 sex
命令用来读取一个字符并赋值给 sex 变量,其中-n
是 read 命令的选项,1
是-n
选项的参数,sex
是 read 命令的参数。
你是否对这些形形色色的选项和参数感到好奇?你是否想知道它们在底层是如何实现的?你是否也想自己动手对它们进行解析?本节就来给你揭晓答案!
死磕这个细节并不是闲得无聊,它能帮助我们理解命令的真正含义。好了,废话不多说,让我们赶紧转入正题吧。
上节我们讲到,一个 Shell 内置命令就是一个内部的函数,一个外部命令就是一个应用程序。内置命令后面附带的所有数据(所有选项和参数)最终都以参数的形式传递给了函数,外部命令后面附带的所有数据(所有选项和参数)最终都以参数的形式传递给了应用程序。
也就是说,不管是内置命令还是外部命令,它后面附带的所有数据都会被“打包”成参数,这些参数有的传递给了函数,有的传递给了应用程序。
有编程经验的读者应该知道,C语言或者 C++ 程序的入口函数是
int main(int argc, char *argv[])
,传递给应用程序的参数最终都被 main 函数接收了。从这个角度看,传递给应用程序的参数其实也是传递给了函数。有了以上认知,我们就不用再区分函数和应用程序了,我们就认为:不管是内置命令还是外部命令,它后面附带的数据最终都以参数的形式传递给了函数。实现一个命令的一项重要工作就是解析传递给函数的参数。
注意,命令后面附带的数据并不是被合并在一起,作为一个参数传递给函数的;这些数据是由空格分隔的,它们被分隔成了几份,就会转换成几个参数。例如
getsum -s 1 -e 100
要向函数传递四个参数,read -n 1 sex
要向函数中传递三个参数。并且,命令后面附带的数据都是“原汁原味”地传递给了函数,比如
getsum -s 1 -e 100
要传递的四个参数分别是 -s、1、-e、100,减号-
也会一起传递过去,在函数内部,减号-
可以用来区分该参数是否是命令的选项。至于在函数内部如何解析这些参数,对于外部命令来说那就是 C/C++ 程序员的工作了,这里不再过多赘述,只给出演示代码。
上节我给大家演示了一个 getsum 程序,本节依然使用该程序演示参数的解析,只是对代码进行了微调。
#include <stdio.h> #include <unistd.h> #include <getopt.h> #include <stdlib.h> int main(int argc, char *argv[]){ int start = 0; int end = 0; int sum = 0; int opt; char *optstring = ":s:e:"; //分析接收到的参数 while((opt = getopt(argc, argv, optstring))!= -1){ switch(opt){ case 's': start = atoi(optarg); break; case 'e': end = atoi(optarg); break; case ':': puts("Missing parameter"); exit(1); } } //检测参数是否有效 if(start<0 || end<=start){ puts("Parameter error"); exit(2); } //打印接收到的参数 printf("Received parameters: "); for(int i=0; i<argc; i++){ printf("%s ", argv[i]); } printf("\n"); //计算累加的和 for(int i=start; i<=end; i++){ sum+=i; } printf("sum=%d\n", sum); return 0; }第 11~20 行是解析参数的关键代码,getopt.h 头文件中的 getopt() 函数是值得重点研究的,有了该函数我们就不用自己去解析参数了,省了很大的力气。
第 27~32 行将接收到的参数打印出来,以便读者更好地观察。
根据上节给出的办法就可以运行 getsum 命令:
[mozhiyan@localhost ~]$ getsum -s 1 -e 100 Received parameters: getsum -s 1 -e 100 sum=5050
所有教程
- socket
- Python基础教程
- C#教程
- MySQL函数
- MySQL
- C语言入门
- C语言专题
- C语言编译器
- C语言编程实例
- GCC编译器
- 数据结构
- C语言项目案例
- C++教程
- OpenCV
- Qt教程
- Unity 3D教程
- UE4
- STL
- Redis
- Android教程
- JavaScript
- PHP
- Mybatis
- Spring Cloud
- Maven
- vi命令
- Spring Boot
- Spring MVC
- Hibernate
- Linux
- Linux命令
- Shell脚本
- Java教程
- 设计模式
- Spring
- Servlet
- Struts2
- Java Swing
- JSP教程
- CSS教程
- TensorFlow
- 区块链
- Go语言教程
- Docker
- 编程笔记
- 资源下载
- 关于我们
- 汇编语言
- 大数据
- 云计算
- VIP视频