C語言中調(diào)用shell指令,根據(jù)調(diào)用指令目的,可以區(qū)分如下兩種情況:
成都創(chuàng)新互聯(lián)公司是網(wǎng)站建設(shè)專家,致力于互聯(lián)網(wǎng)品牌建設(shè)與網(wǎng)絡(luò)營銷,專業(yè)領(lǐng)域包括成都網(wǎng)站建設(shè)、網(wǎng)站設(shè)計、電商網(wǎng)站制作開發(fā)、小程序定制開發(fā)、微信營銷、系統(tǒng)平臺開發(fā),與其他網(wǎng)站設(shè)計及系統(tǒng)開發(fā)公司不同,我們的整合解決方案結(jié)合了恒基網(wǎng)絡(luò)品牌建設(shè)經(jīng)驗和互聯(lián)網(wǎng)整合營銷的理念,并將策略和執(zhí)行緊密結(jié)合,且不斷評估并優(yōu)化我們的方案,為客戶提供全方位的互聯(lián)網(wǎng)品牌整合方案!
一、需要shell指令執(zhí)行某一功能,如創(chuàng)建文件夾,或者刪除文件夾等,程序中不關(guān)注shell指令的輸出,那么可以使用system函數(shù)。
system函數(shù)聲明于stdlib.h, 功能為調(diào)用系統(tǒng)命令,形式為
int system(const char *cmd);
其中cmd為要執(zhí)行的命令字符串,返回值為執(zhí)行是否成功的標記。
比如在Linux下要刪除當前文件夾下的所有擴展名為a的文件,即*.a, 可以寫作
system("rm?*.a?-f");
二、不僅要執(zhí)行shell命令,還需要得知運行的打印結(jié)果,并在程序中使用。
對于此,有兩種方案:
1、用system命令,將輸出重定向到一個txt文件中,執(zhí)行后,再讀取txt文件,使用后刪除。
比如Linux下獲取剩余內(nèi)存的指令可以寫作:
system("freeresult.txt");//結(jié)果重定向到result.txt中。
FILE?*fp?=?fopen("result.txt",?"r");//打開文件。
int?r;
while(fgetc(fp)?!=?'\n');?//忽略第一行。
fscanf(fp,?"%*s%*d%*d%d",r);//讀取第四個域的值,即剩余內(nèi)存值。
printf("剩余內(nèi)存為%d?KB\n",r);//打印結(jié)果。
fclose(fp);//關(guān)閉文件。
unlink("result.txt");//刪除臨時文件。
2、使用重定向,需要經(jīng)過磁盤讀寫,還要刪除文件,相對低效。同時還有可能出現(xiàn)臨時文件和已有文件重名,導(dǎo)致誤刪數(shù)據(jù)的情況。 所以一般使用更方便快捷的方式,即調(diào)用popen。
FILE *popen(const char *cmd, const char *mode);
使用popen的功能和system類似,屬于方法1中執(zhí)行命令和打開文件的一個組合。不過這里用到的文件是隱式的,并不會在系統(tǒng)中真正存在。返回的指針即結(jié)果文件指針。 當使用pclose關(guān)閉后,文件自動銷毀。
方法1中的例子,用popen實現(xiàn)如下:
FILE?*fp?=?popen("free",?"r");//執(zhí)行命令,同時創(chuàng)建管道文件。
int?r;
while(fgetc(fp)?!=?'\n');?//忽略第一行。
fscanf(fp,?"%*s%*d%*d%d",r);//讀取第四個域的值,即剩余內(nèi)存值。
printf("剩余內(nèi)存為%d?KB\n",r);//打印結(jié)果。
pclose(fp);//關(guān)閉并銷毀管道文件。
三、注意事項:
雖然調(diào)用shell命令有時可以大大減少代碼量,甚至有千行代碼不如一句shell的說法,不過調(diào)用shell命令還是有局限性的:
1、使用shell命令會調(diào)用系統(tǒng)資源,效率偏低;
2、不同平臺的shell指令不同,導(dǎo)致可移植性下降;
3、調(diào)用shell命令時會復(fù)制當前進程(fork),如果當前進程的資源占有比較大,會導(dǎo)致瞬間資源占用極大,甚至可能出現(xiàn)失敗。
所以,在編碼時,除非是測試性的代碼,否則在正式代碼中不建議使用shell。
例:
#includestdio.h
intsushu(intx)
{inti;
for(i=2;ix;i++)
if(x%i==0)break;
if(i==x)return1;
elsereturn0;
}
main()
{inti,n=0;
for(i=2;i=1000;i++)
if(sushu(i)==1)n++:
printf("n=%d",n);
}
擴展資料
使用vfork()新建子進程,然后調(diào)用exec函數(shù)族
#includeunistd.h
main()
{
char*argv[]={“l(fā)s”,”-al”,”/etc/passwd”,(char*)};
if(vfork()==0)
{
execv(“/bin/ls”,argv);
}else{
printf(“Thisistheparentprocess\n”);
}
}
其實,你這段代碼執(zhí)行的結(jié)果,將導(dǎo)致一個不確定的行為..
原因是,vfork函數(shù)..
當 調(diào)用 vfork 后,父進程掛起,子進程使用父進程的內(nèi)存空間繼續(xù)執(zhí)行...
重點就在,使用父進程的內(nèi)存空間!子進程的main函數(shù)返回后,會修改棧內(nèi)存(main函數(shù)出棧)。
子進程結(jié)束,父進程繼續(xù)執(zhí)行時,棧中main函數(shù)的上下文已經(jīng)被破壞了,所以將導(dǎo)致不確定的行為(通常情況下是程序崩潰...)
正確的代碼應(yīng)該是
#include?unistd.h
#include?stdio.h
int?main()?{
int?c?=?0;
pid_t?pid?=?vfork();
++c;
printf("c?=?%d\n",?c);
if?(!pid)?{
_exit(0);
}
return?0;
}
子進程調(diào)用_exit() 結(jié)束,才不會破壞棧內(nèi)存。
名稱欄目:C語言vfork函數(shù) c語言for函數(shù)用法
文章網(wǎng)址:http://muchs.cn/article8/dohdoip.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供定制開發(fā)、虛擬主機、微信公眾號、外貿(mào)建站、域名注冊、品牌網(wǎng)站制作
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)