c獲取shell中的引數
問題背景
在Linux中我們會使用到shell,來完成輸入引數的獲取,就如同下面的形式,這種形式在進行多語言程式設計和呼叫有著非常重要的作用
sh test_params 9 8 7
一、傳遞的過程
1.1 原理模型如下:
1.1.1 可執行sh檔案中呼叫C檔案
1.1.2 可執行c檔案中呼叫sh檔案
1.2 從shell呼叫c
根據上述的模型可以知道,通過在shell中加入c程式的編譯執行命令,如[gcc -o filename filename.c]來完成編譯,使用命令[./filename]來進行呼叫
程式碼:
下面的程式碼就是執行編譯後的hello.c產生的hello檔案和對new.c檔案的編譯和執行,new.c中是一個輸入三個數實現求和運算
echo ./hello gcc -o new new.c ./new
結果:
1.3 從c中呼叫shell
使用讀取shell的檔案來完成資料的獲取
if((stream = popen("sh test_adjust.sh", 'r')) == NULL){ fprintf(stderr, "%s", strerror(errno)); return -1; } int i = 0; while (fgets(buf, sizeof(buf), stream) != NULL){ a[i] = (int)buf[0] - 48; i++; }
二、 帶有引數的傳遞
在c中呼叫sh檔案獲取引數之前,先讓sh從命令列獲取引數
2.1 shell獲取引數
shell指令碼的引數傳遞,通過$+n來獲取第幾個引數,0是特殊的引數,是獲取指令碼的名稱
程式碼:
echo $1 echo $2 echo $3 echo $4 echo $5 echo $6 echo $7 echo $12 echo $123 echo $1235
結果:
2.1.1 不輸入引數的呼叫
在shell中使用$0——$n來獲取引數,0代表指令碼,其他的就是依次獲取引數,在不指定的情況下會輸入減一位的值
2.1.2 引數輸入和位置獲取不對應
如果有輸入就要和位置對應起來,否則會預設輸出$後面的值
2.1.3 按位置輸入獲取
按照對應的位置輸入就會出現對應位置的值
2.2 利用c呼叫shell命令獲取shell的引數
上述講述瞭如何利用[sh <filename>.sh param_0 param_1 ... ]來獲取命令列對sh檔案的引數輸入獲取,在c中如何進行呼叫sh指令碼,程式碼如下
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <errno.h> int main(){ char buf[1024]; FILE *stream = NULL; int a[1024]; int ret; memset(buf, 0, sizeof(buf)); if((stream = popen("sh test_adjust.sh 3 5 8", 'r')) == NULL){ //關鍵位置 fprintf(stderr, "%s", strerror(errno)); return -1; } int i = 0; while (fgets(buf, sizeof(buf), stream) != NULL){ a[i] = (int)buf[0] - 48; // 扣掉的48是0的ASCII碼 i++; } printf("the sum of number:%d\n",a[0] +a[1] +a[2]); ret = atoi(buf); if (ret){ printf("command execute succeed!\n"); } else { printf("command execute fail!\n"); } return 0; }
結果
從上述的程式碼我們就實現從c語言中輸入引數給shell,在將shell輸出的引數獲取到進行一個處理。最後可以將這個寫入shell作為一個指令碼
三、總結
介紹瞭如何在將命令列的引數給shell,c語言如何獲取shell的引數,在用shell將其封裝起來。內容類似遞迴,但是在我們實際使用中很重要。我們需要在一段程式碼中引入其他語言的內容,就會出現由於編譯器的問題無法解析這段程式碼,此時我們就需要利用命令列來完成這段程式碼的解析。舉一個例子在web開發中,利用PHP搭建一個web後端,但是由於資料處理方面PHP並不是很適合,此時我們使用的是python,因為無法直接在PHP中對python語法進行編譯執行,就需要使用命令列呼叫python檔案,獲取輸出結果(如下圖)。這就是一個很常見的應用場景之一。shell呼叫c也是一樣的,將其封裝起來,使用shell可以快速完成複雜的呼叫過程,這個過程就是利用資料進行驅動的。