Linux system函数返回值

例:

[cpp] view plain copy

  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脚本正常执行结束的健全代码如下:

[cpp] view plain copy

  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().

时间: 2024-10-04 20:56:13

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

[转]system函数返回值探究

对于system这个函数的功能早就有一定了解,读书期间,就学习了UNIX系统编程这本书,后来买了APUE.我这个人总是有好读书不求甚解的毛病.对于system函数只知其一,不知其二.后来被人问起相关的问题,结果丢了脸.书到用时方恨自己不求甚解.今天仔细探查了下system的一些特性. APUE这本书,对system这个函数已经将的比较明白了,只是它的相关知识稍显分散.最开始我是去网上找的资料,自己写的测试代码,可是还是有很多迷惑的地方.后来才拿起APUE ,好好读了第八章和第十章的相关章节. #

Linux Shell函数返回值

转:http://blog.csdn.net/ithomer/article/details/7954577 Shell函数返回值,一般有3种方式:return,argv,echo 1) return 语句shell函数的返回值,可以和其他语言的返回值一样,通过return语句返回.示例: [javascript] view plain copy print? #!/bin/bash - function mytest() { echo "arg1 = $1" if [ $1 = &q

linux recv函数返回值分析

函数原型: ssize_t recv(int sockfd, void *buf, size_t len, int flags); 该函数第一个参数制定接收端套接字描述符; 第二个参数指明一个缓冲区,该缓冲区用来存放recv函数接收到的数据; 第三个参数指明缓冲区buf的长度; 第四个参数一般置0; (标志位) recv函数返回其实际copy的字节数.如果recv在copy时出错,那么它返回SOCKET_ERROR; 如果recv函数在等待协议接收数据时网络中断了,那么它返回0; recv函数仅

linux编程中接收主函数返回值以及错误码提示

程序A创建子进程,并调用进程B,根据不调用的不同情况,最后显示结果不同. #include <stdio.h> #include <unistd.h> #include <sys/wait.h> #include <sys/types.h> #include <errno.h> int main() { pid_t pid, rpid; int stat; if ((pid = fork()) < 0) { perror("for

python中os.system()的返回值

最近遇到os.system()执行系统命令的情况,上网搜集了一下资料,整理如下,以备不时之需,同时也希望能帮到某些人. 一.python中的 os.system(cmd)的返回值与linux命令返回值(具体参见本文附加内容)的关系 大家都习惯用os.systemv()函数执行linux命令,该函数的返回值十进制数(分别对应一个16位的二进制数).该函数的返回值与 linux命令返回值两者的转换关系为:该函数的返回值(十进制)转化成16二进制数,截取其高八位(如果低位数是0的情况下,有关操作系统的

C语言的函数返回值

一:背景 谈到C语言的函数返回值,可能会感觉很亲切,不就是一个函数返回值嘛,当初学C语言的时候早就学过了很easy嘛,我曾经也是这么想的.后来要上研究生了,研究生阶段搞得就是C,所以又重新开始学习C,学习C的过程中遇到了很多问题,在此博客中一一记录.实际过程中遇到的第一个问题自然就是函数返回值了.如果有人问你在一个函数中声明一个字符串数组,最后再return这个数组.这可以实现嘛?如果是问我我可能会毫不犹豫的说OK.那事实呢?由此本文诞生了...... 二:问题 先看几个实际的例子: #incl

[转]Linux命令的返回值

Linux命令的返回值 对于某些监测脚本和探测命令蛮有用的: 在 Linux 下,不管你是启动一个桌面程序也好,还是在控制台下运行命令,所有的程序在结束时,都会返回一个数字值,这个值叫做返回值,或者称为错误号 ( Error Number ). 在控制台下,有一个特殊的环境变量 $?,保存着前一个程序的返回值,我们可以试试: $ ls *.pngDiagram1.png  eqn.png         peazip.pngeqn4.png      Mandelbrot.png  x2.png

C语言中函数返回值的问题

c语言中有关于在函数返回值的问题,在函数中的局部变量主要是在栈上开辟的,出了函数变量就被回收了,针对函数返回值得问题,给出下面几个比较具体的例子来说明: 函数返回值是在函数中定义的局部变量 这类型的返回值在主函数中是可以使用的,因为返回局部变量值得时候,返回的是值得一个副本,而在主函数中我们需要的也只是这个值而已,因此是可以的,例如 int fun(char *arr) { int num = 0; while (*arr != '\\0') { num = num * 10 + *arr -

函数指针,函数指针数组,函数返回值为函数指针

函数的名字就是函数的首地址:定义函数指针; int (*p)(int ) p为函数指针变量名字,int 为函数的返回值类型为int型:(int)为函数的形参类型为int型, 注:因为优先级所以要用(*p),否则就会p先和后面的()结合为int*p(int),意思就变为p(int)函数的返回值为int* 注:main2()函数中   int (*p[])(int ,int )  为一维数组,下面写错了, #include<stdio.h> #include<stdlib.h> int