Shell命令的選項和參數在本質上到底是什么?
很多 shell 命令都是可以附帶選項和參數的,不同的選項和參數也使得命令的功能細節有所差異。
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
beylze編程學院,一個分享編程知識和seo優化知識的網站。跟著beylze一起學習,每天都有進步。
通俗易懂,深入淺出,一篇文章只講一個知識點。
文章不深奧,不需要鉆研,在公交、在地鐵、在廁所都可以閱讀,隨時隨地漲姿勢。
文章不涉及代碼,不燒腦細胞,人人都可以學習。
當你決定關注beylze(公眾號:beylze),你已然超越了90%的其他從業者!