例:

  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. FreeModbus RTU slave & Modbus RTU master

    一.FreeModbus RTU 协议数据格式 FreeModbus RTU是开源的一个协议,并且使用FreeModbus RTU 只能当做从机Slave,RTU协议中的指令由地址码(一个字节),功能 ...

  2. NYOJ_75 日期计算 (推断这一天是这一年中的第几天)

    题目地址 如题,输入一个日期,格式如:2010 10 24 ,推断这一天是这一年中的第几天. 分析:   官方给的最优答案用了for 和switch语句结合,十分巧妙. 代码 /* 如题,输入一个日期 ...

  3. ORM进阶:Hibernate的优劣对照

    hibernate是一种是轻量级的ORMapping框架.学过EntityFramework的.会感觉挺亲切的. 对于各种层次程序猿对数据库的设计: 小菜程序员这样做:首先考虑数据的存储,对于功能的实 ...

  4. 【剑指Offer面试题】九度OJ1384:二维数组中的查找

    下决心AC全部剑指offer面试题. 九度OJ面试题地址:http://ac.jobdu.com/hhtproblems.php 书籍:何海涛--<剑指Offer:名企面试官精讲典型编程题> ...

  5. thinkphp多层volist实现多表查询

    thinkphp多层volist实现多表查询 一.总结 二.截图 三.代码 1.控制器 2.视图

  6. elasticsearch java 客户端之action简介

    上一篇介绍了elasticsearch的client结构,client只是一个门面,在每个方法后面都有一个action来承接相应的功能.但是action也并非是真正的功能实现者,它只是一个代理,它的真 ...

  7. 桌面版chrome调试APP的webview的步骤:

    1. 在chrome地址栏输入:chrome://inspect/ 2.手机插入电脑USB口,打开开发者选项,OK,可以了. 友情链接:http://www.cnblogs.com/slmk/p/75 ...

  8. 洛谷——P1540 机器翻译

    https://www.luogu.org/problem/show?pid=1540#sub 题目背景 小晨的电脑上安装了一个机器翻译软件,他经常用这个软件来翻译英语文章. 题目描述 这个翻译软件的 ...

  9. [JWT] JWT Signature With RS256 - Learn The Advantages Compared to HS256

    The advantage of RS256 over HS256 is RS256 no longer need to share the secret key between client and ...

  10. 104.tcp多线程读写实现群聊

    客户端: #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include <w ...