首頁 > shell教程 閱讀:0更新時間:2020-03-28 02:15:58

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 命令的選項,1100分別是-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%的其他從業者!

相關文章

優秀教程

国产亚洲欧美日韩