system函数的返回值和执行脚本的返回值
生活随笔
收集整理的這篇文章主要介紹了
system函数的返回值和执行脚本的返回值
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
1、先統(tǒng)一兩個說法:
(1)system返回值:指調(diào)用system函數(shù)后的返回值,比如上例中status為system返回值
(2)shell返回值:指system所調(diào)用的shell命令的返回值,比如上例中,test.sh中返回的值為shell返回值。
2、如何正確判斷test.sh是否正確執(zhí)行? 僅判斷status是否==0?或者僅判斷status是否!=-1?
都錯!
3、man中對于system的說明
RETURN VALUE
?????? The value returned is -1 on error (e.g.? fork() 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). 看得很暈吧?
system函數(shù)對返回值的處理,涉及3個階段: 階段1:創(chuàng)建子進(jìn)程等準(zhǔn)備工作。如果失敗,返回-1。 階段2:調(diào)用/bin/sh拉起shell腳本,如果拉起失敗或者shell未正常執(zhí)行結(jié)束(參見備注1),原因值被寫入到status的低8~15比特位中。system的man中只說明了會寫了127這個值,但實(shí)測發(fā)現(xiàn)還會寫126等值。 階段3:如果shell腳本正常執(zhí)行結(jié)束,將shell返回值填到status的低8~15比特位中。 備注1: 只要能夠調(diào)用到/bin/sh,并且執(zhí)行shell過程中沒有被其他信號異常中斷,都算正常結(jié)束。 比如:不管shell腳本中返回什么原因值,是0還是非0,都算正常執(zhí)行結(jié)束。即使shell腳本不存在或沒有執(zhí)行權(quán)限,也都算正常執(zhí)行結(jié)束。 如果shell腳本執(zhí)行過程中被強(qiáng)制kill掉等情況則算異常結(jié)束。
如何判斷階段2中,shell腳本是否正常執(zhí)行結(jié)束呢?系統(tǒng)提供了宏:WIFEXITED(status)。如果WIFEXITED(status)為真,則說明正常結(jié)束。 如何取得階段3中的shell返回值?你可以直接通過右移8bit來實(shí)現(xiàn),但安全的做法是使用系統(tǒng)提供的宏:WEXITSTATUS(status)。
由于我們一般在shell腳本中會通過返回值判斷本腳本是否正常執(zhí)行,如果成功返回0,失敗返回正數(shù)。 所以綜上,判斷一個system函數(shù)調(diào)用shell腳本是否正常結(jié)束的方法應(yīng)該是如下3個條件同時成立: (1)-1 != status (2)WIFEXITED(status)為真 (3)0 == WEXITSTATUS(status)
注意: 根據(jù)以上分析,當(dāng)shell腳本不存在、沒有執(zhí)行權(quán)限等場景下時,以上前2個條件仍會成立,此時WEXITSTATUS(status)為127,126等數(shù)值。 所以,我們在shell腳本中不能將127,126等數(shù)值定義為返回值,否則無法區(qū)分中是shell的返回值,還是調(diào)用shell腳本異常的原因值。shell腳本中的返回值最好多1開始遞增。
判斷shell腳本正常執(zhí)行結(jié)束的健全代碼如下: [cpp]?view plaincopy #include?<stdio.h>?? #include?<stdlib.h>?? #include?<sys/wait.h>?? #include?<sys/types.h>?? ?? int?main()?? {?? ????pid_t?status;?? ?? ?? ????status?=?system("./test.sh");?? ?? ????if?(-1?==?status)?? ????{?? ????????printf("system?error!");?? ????}?? ????else?? ????{?? ????????printf("exit?status?value?=?[0x%x]\n",?status);?? ?? ????????if?(WIFEXITED(status))?? ????????{?? ????????????if?(0?==?WEXITSTATUS(status))?? ????????????{?? ????????????????printf("run?shell?script?successfully.\n");?? ????????????}?? ????????????else?? ????????????{?? ????????????????printf("run?shell?script?fail,?script?exit?code:?%d\n",?WEXITSTATUS(status));?? ????????????}?? ????????}?? ????????else?? ????????{?? ????????????printf("exit?status?=?[%d]\n",?WEXITSTATUS(status));?? ????????}?? ????}?? ?? ????return?0;?? }??
WIFEXITED(stat_val) Evaluates to a non-zero value if status
was returned for a child process that
terminated normally.
WEXITSTATUS(stat_val) If the value of WIFEXITED(stat_val) is
non-zero, this macro evaluates to the
low-order 8 bits of the status argument
that the child process passed to _exit()
or exit(), or the value the child
process returned from main(). 言歸正傳,下面這段代碼則會導(dǎo)致程序system調(diào)用總是返回-1
? [cpp]?view plaincopy #include?<stdio.h>?? #include?<stdlib.h>?? #include?<signal.h>?? ?? int?main(int?argc?,char?*argv[])?? {?? ????signal(SIGCHLD,SIG_IGN);?? ????int?status?=?system("ls?-l");?? ????if(status?==?-1)??? ????{????? ????????printf("system?fork?faild?!\n");?? ????}????? ????else???? ????{????? ????????printf("exit?status?value?=?[0x%x]\n",?status);???? ?? ????????if?(WIFEXITED(status))???? ????????{????? ????????????if?(0?==?WEXITSTATUS(status))???? ????????????{????? ????????????????printf("run?shell?script?successfully.\n");???? ????????????}????? ????????????else???? ????????????{????? ????????????????printf("run?shell?script?fail,?script?exit?code:?%d\n",?WEXITSTATUS(status));???? ????????????}????? ????????}????? ????????else???? ????????{????? ????????????printf("exit?status?=?[%d]\n",?WEXITSTATUS(status));???? ????????}????? ????}????? ????return?0;?? } ?
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎
2、如何正確判斷test.sh是否正確執(zhí)行? 僅判斷status是否==0?或者僅判斷status是否!=-1?
都錯!
3、man中對于system的說明
RETURN VALUE
?????? The value returned is -1 on error (e.g.? fork() 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). 看得很暈吧?
system函數(shù)對返回值的處理,涉及3個階段: 階段1:創(chuàng)建子進(jìn)程等準(zhǔn)備工作。如果失敗,返回-1。 階段2:調(diào)用/bin/sh拉起shell腳本,如果拉起失敗或者shell未正常執(zhí)行結(jié)束(參見備注1),原因值被寫入到status的低8~15比特位中。system的man中只說明了會寫了127這個值,但實(shí)測發(fā)現(xiàn)還會寫126等值。 階段3:如果shell腳本正常執(zhí)行結(jié)束,將shell返回值填到status的低8~15比特位中。 備注1: 只要能夠調(diào)用到/bin/sh,并且執(zhí)行shell過程中沒有被其他信號異常中斷,都算正常結(jié)束。 比如:不管shell腳本中返回什么原因值,是0還是非0,都算正常執(zhí)行結(jié)束。即使shell腳本不存在或沒有執(zhí)行權(quán)限,也都算正常執(zhí)行結(jié)束。 如果shell腳本執(zhí)行過程中被強(qiáng)制kill掉等情況則算異常結(jié)束。
如何判斷階段2中,shell腳本是否正常執(zhí)行結(jié)束呢?系統(tǒng)提供了宏:WIFEXITED(status)。如果WIFEXITED(status)為真,則說明正常結(jié)束。 如何取得階段3中的shell返回值?你可以直接通過右移8bit來實(shí)現(xiàn),但安全的做法是使用系統(tǒng)提供的宏:WEXITSTATUS(status)。
由于我們一般在shell腳本中會通過返回值判斷本腳本是否正常執(zhí)行,如果成功返回0,失敗返回正數(shù)。 所以綜上,判斷一個system函數(shù)調(diào)用shell腳本是否正常結(jié)束的方法應(yīng)該是如下3個條件同時成立: (1)-1 != status (2)WIFEXITED(status)為真 (3)0 == WEXITSTATUS(status)
注意: 根據(jù)以上分析,當(dāng)shell腳本不存在、沒有執(zhí)行權(quán)限等場景下時,以上前2個條件仍會成立,此時WEXITSTATUS(status)為127,126等數(shù)值。 所以,我們在shell腳本中不能將127,126等數(shù)值定義為返回值,否則無法區(qū)分中是shell的返回值,還是調(diào)用shell腳本異常的原因值。shell腳本中的返回值最好多1開始遞增。
判斷shell腳本正常執(zhí)行結(jié)束的健全代碼如下: [cpp]?view plaincopy
was returned for a child process that
terminated normally.
WEXITSTATUS(stat_val) If the value of WIFEXITED(stat_val) is
non-zero, this macro evaluates to the
low-order 8 bits of the status argument
that the child process passed to _exit()
or exit(), or the value the child
process returned from main(). 言歸正傳,下面這段代碼則會導(dǎo)致程序system調(diào)用總是返回-1
? [cpp]?view plaincopy
總結(jié)
以上是生活随笔為你收集整理的system函数的返回值和执行脚本的返回值的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++(STL):17---deque之
- 下一篇: 架构分享--微博架构