例:

  1. status = system("./test.sh");
1、先统一两个说法:
(1)system返回值:指调用system函数后的返回值,比如上例中status为system返回值
(2)shell返回值:指system所调用的shell命令的返回值,比如上例中,test.sh中返回的值为shell返回值。
 
2、如何正确判断test.sh是否正确执行?
仅判断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函数对返回值的处理,涉及3个阶段:
阶段1:创建子进程等准备工作。如果失败,返回-1。
阶段2:调用/bin/sh拉起shell脚本,如果拉起失败或者shell未正常执行结束(参见备注1),原因值被写入到status的低8~15比特位中。system的man中只说明了会写了127这个值,但实测发现还会写126等值。
阶段3:如果shell脚本正常执行结束,将shell返回值填到status的低8~15比特位中。
备注1:
只要能够调用到/bin/sh,并且执行shell过程中没有被其他信号异常中断,都算正常结束。
比如:不管shell脚本中返回什么原因值,是0还是非0,都算正常执行结束。即使shell脚本不存在或没有执行权限,也都算正常执行结束。
如果shell脚本执行过程中被强制kill掉等情况则算异常结束。
 
如何判断阶段2中,shell脚本是否正常执行结束呢?系统提供了宏:WIFEXITED(status)。如果WIFEXITED(status)为真,则说明正常结束。
如何取得阶段3中的shell返回值?你可以直接通过右移8bit来实现,但安全的做法是使用系统提供的宏:WEXITSTATUS(status)。
 
 
由于我们一般在shell脚本中会通过返回值判断本脚本是否正常执行,如果成功返回0,失败返回正数。
所以综上,判断一个system函数调用shell脚本是否正常结束的方法应该是如下3个条件同时成立:
(1)-1 != status
(2)WIFEXITED(status)为真
(3)0 == WEXITSTATUS(status)
 
注意:
根据以上分析,当shell脚本不存在、没有执行权限等场景下时,以上前2个条件仍会成立,此时WEXITSTATUS(status)为127,126等数值。
所以,我们在shell脚本中不能将127,126等数值定义为返回值,否则无法区分中是shell的返回值,还是调用shell脚本异常的原因值。shell脚本中的返回值最好多1开始递增。
 
判断shell脚本正常执行结束的健全代码如下:
 
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/wait.h>
  4. #include <sys/types.h>
  5. int main()
  6. {
  7. pid_t status;
  8. status = system("./test.sh");
  9. if (-1 == status)
  10. {
  11. printf("system error!");
  12. }
  13. else
  14. {
  15. printf("exit status value = [0x%x]\n", status);
  16. if (WIFEXITED(status))
  17. {
  18. if (0 == WEXITSTATUS(status))
  19. {
  20. printf("run shell script successfully.\n");
  21. }
  22. else
  23. {
  24. printf("run shell script fail, script exit code: %d\n", WEXITSTATUS(status));
  25. }
  26. }
  27. else
  28. {
  29. printf("exit status = [%d]\n", WEXITSTATUS(status));
  30. }
  31. }
  32. return 0;
  33. }
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().

Linux system函数返回值的更多相关文章

  1. [转]system函数返回值探究

    对于system这个函数的功能早就有一定了解,读书期间,就学习了UNIX系统编程这本书,后来买了APUE.我这个人总是有好读书不求甚解的毛病.对于system函数只知其一,不知其二.后来被人问起相关的 ...

  2. Linux Shell函数返回值

    转:http://blog.csdn.net/ithomer/article/details/7954577 Shell函数返回值,一般有3种方式:return,argv,echo 1) return ...

  3. Linux Shell 函数返回值

    Shell函数返回值,常用的两种方式:return,echo 1) return 语句 shell函数的返回值,可以和其他语言的返回值一样,通过return语句返回. 示例: #!/bin/sh fu ...

  4. linux shell 函数返回值问题(超过255)

    最近再写一个shell测试的时候出现问题,函数返回值异常 用shell计算斐波那契数列数列,写了一个shell函数,然后调用的,验证的时候我只随便计算了几个数(10以内),确认结果是正确的就提交了,后 ...

  5. linux recv函数返回值分析

    函数原型: ssize_t recv(int sockfd, void *buf, size_t len, int flags); 该函数第一个参数制定接收端套接字描述符; 第二个参数指明一个缓冲区, ...

  6. [转]Linux命令的返回值

    Linux命令的返回值 对于某些监测脚本和探测命令蛮有用的: 在 Linux 下,不管你是启动一个桌面程序也好,还是在控制台下运行命令,所有的程序在结束时,都会返回一个数字值,这个值叫做返回值,或者称 ...

  7. c语言main函数返回值、参数详解(返回值是必须的,0表示正常退出)

    C语言Main函数返回值 main函数的返回值,用于说明程序的退出状态.如果返回0,则代表程序正常退出:返回其它数字的含义则由系统决定.通常,返回非零代表程序异常退出. 很多人甚至市面上的一些书籍,都 ...

  8. linux system函数分析

    system函数是在应用编程里面想调用外部命令时最方便的方式了,除非想要获取命令行执行的输出信息, 那system就不行了,需要用popen.但是system内部具体怎么实现及怎么处理它的返回值经常被 ...

  9. C语言:将3*4矩阵中找出行最大,列最小的那个元素。-将低于平均值的人数作为函数返回值,将低于平均分的分数放入below数组中。

    //将3*4矩阵中找出行最大,列最小的那个元素. #include <stdio.h> #define M 3 #define N 4 void fun(int (*a)[N]) { ,j ...

随机推荐

  1. shell date 命令说明

    shell date 命令说明 使用方法:date [选项]... [+格式] 或:date [-u|--utc|--universal] [MMDDhhmm[[CC]YY][.ss]] 以给定的格式 ...

  2. SDUTOJ 2711 4-2 电子时钟中的运算符重载

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvUl9NaXNheWE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA ...

  3. gullo.me 的 natvps

    gullo.me 的 natvps 1. 在下面的地址中输入内网 IP,查看许可的网络资源 https://hosting.gullo.me/plugin/support_manager/knowle ...

  4. RelativeLayout-属性大全

    // 相对于给定ID控件 <!--将该控件的底部置于给定ID的控件之上--> android:layout_above <!--将该控件的底部置于给定ID的控件之下--> an ...

  5. php课程 18-60 cookie和session的最主要区别是什么

    php课程 18-60 cookie和session的最主要区别是什么 一.总结 一句话总结:存储位置不同:cookie存储在客户端:session存储在服务端. 1.cookie和session在p ...

  6. stm8开发环境配置及测试

    需要准备的软件,硬件,IAR for stm8 (EWSTM8).stm8s标准固件库.ST-LINK.STM8s003f3核心板 安装IAR(其中包括st-link的驱动), 到这个网址下载stm8 ...

  7. 3.SOAP和WSDL的一些必要知识

    转自:https://www.cnblogs.com/JeffreySun/archive/2009/12/14/1623766.html SOAP和WSDL对Web Service.WCF进行深入了 ...

  8. Ajax : load()

    <body> <input type="button" value="Ajax" /> <div id="box&quo ...

  9. 用Zebra打造Linux下小型路由器

    用Zebra打造Linux下小型路由器 现在的Internet网络相当庞大,不可能在不同的网络之间建立直接的连接,所以这时就必须用路由器为不同网络之间的通信提供路径选择.Linux下搭建路由器价格非常 ...

  10. 理解String的compareTo()方法返回值

    compareTo()的返回值是整型,它是先比较对应字符的大小(ASCII码顺序), 如果第一个字符和参数的第一个字符不等,结束比较,返回他们之间的差值. 如果第一个字符和参数的第一个字符相等,则以第 ...