工作中,在做C軟件開發與Linux系統交互部分時,經常會遇到C碼需要調用shell命令或shell腳本情況。那C碼如何調用shell命令或腳本的呢?
以下提供兩個示例函數,演示其調用方法:
//[1]C調用shell命令
#include <stdlib.h>
#include <stdio.h>
int subif_ipaddr_set(void)
{
char cmd[128] = { 0 };
char *if_name = "eth1.1";
char *ipaddr_str = "192.168.0.101";
sprintf(cmd, "ifconfig %s %s/16", if_name, ipaddr_str);
return system(cmd);
}
//[2]C調用shell腳本
#include <stdlib.h>
#include <stdio.h>
int spm_script_exec(void)
{
char cmd[128] = { 0 };
char *board_name = "lpu";
char *version_str = "debug";
sprintf(cmd, "bash ../../os/spm_prestart.sh %s %s", board_name, version_str);
printf("Exec cmd[%s]...", cmd); // 可以打印看看需要執行的shell命令
return system(cmd);
}
從上述示例可以看出,C碼調用shell命令或shell腳本的基本方法都是一樣的,通過system()函數調用shell命令行字符串。
唯一需要注意的地方就是,如果執行system()調用的是linux命令,因其在PATH環境變量下,所以不用考慮命令路徑問題;但是執行system()調用shell腳本,需要明確指定腳本所在的絕對路徑,或者被調用腳本與調用C進程的相對路徑(個人推薦)。當然,你也可以把手動把shell腳本路徑添加到環境變量中,這樣調用一個私有腳本與調用shell命令看起來就沒有任何區別啦!
特別說明:
1、system()會調用fork()產生子進程, 由子進程來調用/bin/sh-c string 來執行參數string 字符串所代表的命令, 此命令執行完後隨即返回原調用的進程。也即C程序與shell執行程序不在同一進程;
2、在調用system()期間SIGCHLD 信號會被暫時擱置,SIGINT 和SIGQUIT 信號則會被忽略。也即通過system調用的shell程序執行時不可通過ctrl+c中斷,通過SIGCHLD信號做的進程監控,父進程退出,shell執行子進程不會被立即退出;
對於system返回值,需要注意:
1、如果 system()在調用/bin/sh 時失敗則返回127,其他失敗原因返回-1;
2、若參數string 爲空指針(NULL),則返回非零值;
3、如果system()調用成功,則最後會返回執行shell 命令後的返回值,但是此返回值也有可能爲system()調用/bin/sh 失敗所返回的127,因此最好再檢查errno 來確認執行成功與否。
更多的注意事項,可自行百度一下,此處不再贅述!