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脚本正常执行结束的健全代码如下:
[cpp] view plaincopy
  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().

言归正传,下面这段代码则会导致程序system调用总是返回-1
[cpp] view plaincopy
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <signal.h>
  4. int main(int argc ,char *argv[])
  5. {
  6. signal(SIGCHLD,SIG_IGN);
  7. int status = system("ls -l");
  8. if(status == -1)
  9. {
  10. printf("system fork faild !\n");
  11. }
  12. else
  13. {
  14. printf("exit status value = [0x%x]\n", status);
  15. if (WIFEXITED(status))
  16. {
  17. if (0 == WEXITSTATUS(status))
  18. {
  19. printf("run shell script successfully.\n");
  20. }
  21. else
  22. {
  23. printf("run shell script fail, script exit code: %d\n", WEXITSTATUS(status));
  24. }
  25. }
  26. else
  27. {
  28. printf("exit status = [%d]\n", WEXITSTATUS(status));
  29. }
  30. }
  31. return 0;
  32. }

system函数的返回值和执行脚本的返回值相关推荐

  1. redis有值查询返回null_redis运行lua脚本hmget返回值为空判断问题-Go语言中文社区...

    1.redis中准备测试数据 hmset test abcd 123 ABCD 456 hgetall test 2.网上有人说用内置函数next()判断 redis-cli -c -p 8000 - ...

  2. python接口返回状态码,Python脚本接口返回正常,状态码405

    最近些Python接口脚本时调用post接口时返回结果正常,状态码却不对. ,代码如下: 此接口完成的功能为新增一个角色,角色添加成功返回角色的id信息,但是状态码为405,405是Method No ...

  3. linux下system函数详解

    一.system函数的简单介绍 头文件 #include <stdlib.h>函数定义int system(const char * string); 函数说明 system()会调用fo ...

  4. linux下system函数的深入理解

    这几天调程序(嵌入式linux),发现程序有时就莫名其妙的死掉,每次都定位在程序中不同的system()函数,直接在shell下输入system()函数中调用的命令也都一切正常.就没理这个bug,以为 ...

  5. system函数的总结

    最近在看APUE第10章中关于system函数的POSIX.1的实现.关于POSIX.1要求system函数忽略SIGINT和SIGQUIT,并且阻塞信号SIGCHLD的论述,理解得不是很透彻,本文就 ...

  6. system函数深度理解

    转载地址:https://www.cnblogs.com/tdyizhen1314/p/4902560.html 注:从其它地方转的非常好的一篇文章,值得深究! 这几天调程序(嵌入式linux),发现 ...

  7. C++之system函数

    转载自:http://www.xuebuyuan.com/2119209.html 1.windows操作系统下system () 函数详解(主要是在C语言中的应用) 函数名: system 功 能: ...

  8. shell中执行脚本并显示到终端和保存到日志文件中

    我们知道,在shell中执行脚本会返回一定信息到终端屏幕上 ,但是有一些特殊情况,如以下情况: 1)显示到终端中 echo  "abck" 以上在手动执行脚本中是可以的,如果是编写 ...

  9. abaqus的python安装文件在哪_python、abaqus执行脚本路径

    python中获取执行脚本路径方法 1.sys.path[0]:获取执行脚本目录绝对路径 #每次执行脚本时,python会将执行脚本目录加入PYTHONPATH环境变量中(sys.path获取) #! ...

最新文章

  1. SQL语句关键字执行顺序
  2. CMMI5级组织如何设定年度目标
  3. Union-Find 算法应用
  4. undertow服务器分析_进入Undertow Web服务器
  5. jQuery选择id属性带有.点符号元素的方法
  6. [转载]Hamachi 安装过程
  7. 试戴系统完全开放—zoomla!逐浪cms在后4.6时代的又一个亮点
  8. 通过char与varchar的区别,学习可变长的字符类型
  9. Windows2003远程桌面无用户限制
  10. java计算经纬度距离_LeetCode 题解 |461. 汉明距离
  11. 什么是 npm ?npm 下载安装使用
  12. C语言测量平差课程设计,测量平差课程设计-20210419024415.docx-原创力文档
  13. CS5211替代LT7211B参数特性与优势|DP转LVDS方案
  14. clickhouse - 第三章:内置对象 之 第二节:table表操作 - 创建表与删除表
  15. 考研英语(二)——简单句
  16. 如何有效地阅读技术书籍
  17. Cocos2dx版本介绍【至3.10版】
  18. 每日词根——sol(完整可靠安慰,太阳严肃)
  19. 产品三维模型在线展示
  20. 9个适合上班族晚上在家就能赚钱的副业推荐(建议收藏)

热门文章

  1. asterisk1.8 账号信息mysql存储(动态)
  2. java java.lang_Java之java.lang.IllegalMonitorStateException
  3. 【转】Win10系统怎么设置无线做AP热点_win10设置无线为ap热点的步骤
  4. 【转】如何在 Visual Studio 2019 中连接中国版 Azure
  5. turtlebot3入门教程
  6. Asp.Net WebForm生命周期的详解
  7. 【Python CheckiO 题解】Remove Accents
  8. PWN-COMPETITION-HGAME2022-Week1
  9. 【Python学习】 - anaconda中spyder的常用快捷键总结
  10. 【POJ - 2632】Crashing Robots(模拟)