成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Linux system函數(shù)的正確應(yīng)用和異常處理

系統(tǒng) Linux
Linux系統(tǒng)中的system函數(shù)作為Linux應(yīng)用開發(fā)工程師來說是一個(gè)非常方便的調(diào)用shell腳本的方法,但是不理解system函數(shù)本身的調(diào)用機(jī)制,不進(jìn)行相應(yīng)的出錯(cuò)處理,很容易造成程序的異常和bug。

Linux系統(tǒng)中的system函數(shù)作為Linux應(yīng)用開發(fā)工程師來說是一個(gè)非常方便的調(diào)用shell腳本的方法,但是不理解system函數(shù)本身的調(diào)用機(jī)制,不進(jìn)行相應(yīng)的出錯(cuò)處理,很容易造成程序的異常和bug。

一、system()理解

功能:system()函數(shù)調(diào)用“/bin/sh -c command”執(zhí)行特定的命令,阻塞當(dāng)前進(jìn)程直到command命令執(zhí)行完畢

原型:

int system(const char *command);

返回值:

如果無法啟動(dòng)shell運(yùn)行命令,system將返回127;出現(xiàn)不能執(zhí)行system調(diào)用的其他錯(cuò)誤時(shí)返回-1。如果system能夠順利執(zhí)行,返回那個(gè)命令的退出碼。

說明:

man幫助:

       #include <stdlib.h>

       int system(const char *command);

DESCRIPTION 

       system()  executes a command specified in command by calling /bin/sh -c 

       command, and returns after the command has been completed.  During exe- 

       cution  of the command, SIGCHLD will be blocked, and SIGINT and SIGQUIT 

       will be ignored.

RETURN VALUE 

       The value returned is -1 on  error  (e.g.   fork(2)  failed),  and  the 

       return  status  of the command otherwise.  This latter return status is 

       in the format specified in wait(2).  Thus, the exit code of the command 

       will  be  WEXITSTATUS(status).   In case /bin/sh could not be executed, 

       the exit status will be that of a command that does exit(127).

       If the value of command is NULL, system() returns non-zero if the shell 

       is available, and zero if not.

       system() does not affect the wait status of any other children.

二、system()函數(shù)原理

system函數(shù)執(zhí)行時(shí),會(huì)調(diào)用fork、execve、waitpid等函數(shù)。

Linux版system函數(shù)的源碼:

 

  1. int system(const char * cmdstring) 
  2.  { 
  3.      pid_t pid; 
  4.      int status; 
  5.      if(cmdstring == NULL){         
  6.           return (1); 
  7.      } 
  8.      if((pid = fork())<0){ 
  9.              status = -1; 
  10.      } 
  11.      else if(pid == 0){ 
  12.          execl("/bin/sh", "sh", "-c", cmdstring, (char *)0); 
  13.          _exit(127); //子進(jìn)程正常執(zhí)行則不會(huì)執(zhí)行此語句 
  14.         } 
  15.      else{ 
  16.              while(waitpid(pid, &status, 0) < 0){ 
  17.                  if(errno != EINTER){ 
  18.                      status = -1; 
  19.                      break; 
  20.                  } 
  21.              } 
  22.          } 
  23.          return status; 
  24.  } 

 

函數(shù)說明 

system()會(huì)調(diào)用fork()產(chǎn)生子進(jìn)程,由子進(jìn)程來調(diào)用/bin/sh-c string來執(zhí)行參數(shù)string字符串所代表的命令,此命>令執(zhí)行完后隨即返回原調(diào)用的進(jìn)程。 

在調(diào)用system()期間SIGCHLD 信號(hào)會(huì)被暫時(shí)擱置,SIGINT和SIGQUIT 信號(hào)則會(huì)被忽略。 

返回值 

=-1:出現(xiàn)錯(cuò)誤  

=0:調(diào)用成功但是沒有出現(xiàn)子進(jìn)程  

>0:成功退出的子進(jìn)程的id 

如果system()在調(diào)用/bin/sh時(shí)失敗則返回127,其他失敗原因返回-1。若參數(shù)string為空指針(NULL),則返回非零值>。如果system()調(diào)用成功則最后會(huì)返回 

執(zhí)行shell命令后的返回值,但是此返回值也有可能為 system()調(diào)用/bin/sh失敗所返回的127,因此最好能再檢查errno 來確認(rèn)執(zhí)行成功。 

附加說明 

在編寫具有SUID/SGID權(quán)限的程序時(shí)請勿使用system(),system()會(huì)繼承環(huán)境變量,通過環(huán)境變量可能會(huì)造成系統(tǒng)安全的問題。

system函數(shù)對返回值的處理,涉及3個(gè)階段:

階段1:創(chuàng)建子進(jìn)程等準(zhǔn)備工作。如果失敗,返回-1。 

階段2:調(diào)用/bin/sh拉起shell腳本,如果拉起失敗或者shell未正常執(zhí)行結(jié)束(參見備注1),原因值被寫入到status的低8~15比特位中。system的man中只說明了會(huì)寫了127這個(gè)值,但實(shí)測發(fā)現(xiàn)還會(huì)寫126等值。 

階段3:如果shell腳本正常執(zhí)行結(jié)束,將shell返回值填到status的低8~15比特位中。 

備注1: 

只要能夠調(diào)用到/bin/sh,并且執(zhí)行shell過程中沒有被其他信號(hào)異常中斷,都算正常結(jié)束。 

比如:不管shell腳本中返回什么原因值,是0還是非0,都算正常執(zhí)行結(jié)束。即使shell腳本不存在或沒有執(zhí)行權(quán)限,也都算正常執(zhí)行結(jié)束。 

如果shell腳本執(zhí)行過程中被強(qiáng)制kill掉等情況則算異常結(jié)束。

如何判斷階段2中,shell腳本子進(jìn)程是否正常執(zhí)行結(jié)束呢?系統(tǒng)提供了宏:WIFEXITED(status)。如果WIFEXITED(status)為真,則說明正常結(jié)束。 

如何取得階段3中的shell返回值?你可以直接通過右移8bit來實(shí)現(xiàn),但安全的做法是使用系統(tǒng)提供的宏:WEXITSTATUS(status)。

由于我們一般在shell腳本中會(huì)通過返回值判斷本腳本是否正常執(zhí)行,如果成功返回0,失敗返回正數(shù)。 

所以綜上,判斷一個(gè)system函數(shù)調(diào)用shell腳本是否正常結(jié)束的方法應(yīng)該是如下3個(gè)條件同時(shí)成立: 

(1)-1 != status 

(2)WIFEXITED(status)為真 

(3)0 == WEXITSTATUS(status) 

注意: 

根據(jù)以上分析,當(dāng)shell腳本不存在、沒有執(zhí)行權(quán)限等場景下時(shí),以上前2個(gè)條件仍會(huì)成立,此時(shí)WEXITSTATUS(status)為127,126等數(shù)值。 

所以,我們在shell腳本中不能將127,126等數(shù)值定義為返回值,否則無法區(qū)分中是shell的返回值,還是調(diào)用shell腳本異常的原因值。shell腳本中的返回值最好多1開始遞增。

示例程序:

 

  1. #include <stdio.h> 
  2. #include <unistd.h> 
  3. #include <stdlib.h> 
  4.  
  5. #define EXIT_ERR(m) \ 
  6. do\ 
  7. {\ 
  8.     perror(m);\ 
  9.     exit(EXIT_FAILURE);\ 
  10. }\ 
  11. while (0);\ 
  12.   
  13. int main(void) 
  14.     int status ; 
  15.     status = system("ls -l|wc -l"); 
  16.   
  17.     if(status == -1){ 
  18.         EXIT_ERR("system error"); 
  19.     } 
  20.   
  21.     else{ 
  22.         if(WIFEXITED(status)) 
  23.         { 
  24.             if(WEXITSTATUS(status) == 0) 
  25.                 printf("run command successful\n"); 
  26.             else 
  27.                 printf("run command fail and exit code is %d\n",WEXITSTATUS(status)); 
  28.         } 
  29.         else 
  30.             printf("exit status = %d\n",WEXITSTATUS(status)); 
  31.     } 
  32.     return 0; 

 

運(yùn)行結(jié)果:

 

責(zé)任編輯:奔跑的冰淇淋 來源: 嵌入式linux中文站
相關(guān)推薦

2010-05-25 18:01:35

linux MySQL

2010-05-28 15:16:40

MySQL 資源

2010-02-01 15:26:44

C++ inline函

2010-05-28 19:20:36

MySQL mysql

2009-12-07 14:38:14

PHP foreach

2010-02-22 10:42:12

WCF Stream

2010-08-16 10:10:27

DB2常用函數(shù)

2010-07-21 10:50:48

SQL Server存

2010-02-22 14:09:08

WCF Dispose

2021-07-02 16:13:01

區(qū)塊鏈金融數(shù)據(jù)庫

2010-07-26 16:11:45

Microsoft S

2010-07-20 13:26:43

2010-07-05 14:34:19

2010-02-05 17:49:24

C++常量引用

2010-07-26 17:43:34

SQL Server

2010-02-05 14:12:46

C++聲明放置

2010-03-04 13:30:11

Python file

2010-03-04 09:40:52

Python Clas

2010-06-10 17:19:05

MySQL數(shù)據(jù)庫

2010-08-11 15:48:04

DB2編程
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 一区二区激情 | 日韩久久久久久 | 欧美一级www片免费观看 | 播放一级毛片 | zzzwww在线看片免费 | 日韩精品在线网站 | 在线区 | 欧美午夜视频 | 成人a视频在线观看 | 在线观看国产网站 | 国产成人精品在线 | 国产日韩精品一区二区 | a黄视频| 一级日韩| 蜜桃精品视频在线 | 色综合久久久 | 亚洲天堂精品久久 | 免费播放一级片 | 国产一区二区三区 | 日韩高清国产一区在线 | 欧美www在线观看 | 国产1区2区3区 | 久久99精品久久久久久 | 欧美亚洲一级 | 狠狠色狠狠色综合系列 | 亚洲精品乱码久久久久久蜜桃 | 狠狠干天天干 | 日本不卡高清视频 | 久久久久久国产精品三区 | 国产高清一区二区三区 | 天天狠狠 | 国产91观看| 亚洲一区二区三区久久 | 亚洲国产一区二区三区在线观看 | 性色在线 | 日本一卡精品视频免费 | 欧美电影在线 | 亚洲综合大片69999 | 亚洲激情在线观看 | 欧美日韩欧美 | 中文字幕高清免费日韩视频在线 |