美文网首页PHP实战
Linux system 函数

Linux system 函数

作者: 小小小码农 | 来源:发表于2016-11-26 18:40 被阅读208次

最近工作中在Linux下,某些指定的程序需要调用指定的shell脚本完成指定工作,以前也曾经做过类似的功能,调用system函数执行指定的脚本,以前并不关心shell脚本是否执行成功了,现在的功能需要根据shell脚本执行成功与否,于是查询了下system函数的说明,有此文以做笔记之用。

system 函数说明

#include <stdlib.h>

int system(const char *command);

功能:调用/bin/sh -c 执行指定的脚本 command

常规使用方法:

int ret = system("./test.sh");

关于返回值:

  • system 返回值,调用函数后的返回值
  • shell 返回值,指脚本执行后的返回值

如何判断脚本是否执行成功

  • ret == 0
  • ret != -1
    以上两个对于返回值的判定,是经常被使用的,但是正确么。。。

答案是都错

system 返回值说明

man手册

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).If the value of command is NULL, system() returns non-zero if the shell is available, and zero if not.system() does not affect the wait status of any other children.

看着挺晕的,但是如果对于system的执行过程了解的话,就很容易理解了,函数执行分为以下几个阶段。
阶段1:创建子进程等准备工作。如果失败,返回-1
阶段2:调用/bin/sh拉起脚本,如果拉起失败或者shell未正常执行,原因值被写入ret中
阶段3:如果shell脚本执行成功,shell脚本的返回值写入ret中

从上面可知,不管shell脚本返回什么值,只要调用了/bin/sh,并且执行过程没有被信号中断,都算正常结束。因为脚本是在子进程中执行的,所以要想获取脚本是否执行成功的方法只能用系统提供的两个宏。

WIFEXITED用来判断阶段二的返回值
WEXITSTATUS用来判断阶段三的返回值

由于我们一般在shell中会通过返回值判断脚本是否执行成功,成功返回0,成功返回整数。所以判断一个脚本是否执行成功,应该满足三个条件:

  • -1 != ret
  • WIFEXITED(ret)为真
  • 0 == WEXITSTATUS(ret)

注意:当shell脚本不存在时、没有执行条件等,前两个条件也会成立,此时WEXITSTATUS(ret)为127,所以shell脚本中不能将127作为返回值,shell脚本中的异常返回值最好从1开始递增,成功返回0。

实例代码

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/wait.h>


int main(int argc, char *argv[])
{

    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;
}

总结

system用起来,看则简单,实则不那么简单,有很多隐藏的坑,需要自己深入理解原理,才能更好地使用,也可以用其他实现方式完成相同的功能。
最后对自己说,多写,多思,多总结

相关文章

  • Linux system 函数

    最近工作中在Linux下,某些指定的程序需要调用指定的shell脚本完成指定工作,以前也曾经做过类似的功能,调用s...

  • QT调用外部程序

    1、通过调用Linux C 函数 system("calc.exe"); 2、通过QProcess 阻塞调用 ...

  • Linux time system

    Linux time system Linux中跟时间有关的函数变量有很多,但是对开发者来说无非就是用了计时/延时...

  • Android notes

    The Android operating system is a multi-user Linux system...

  • Linux 防火墙之 firewalld 的基本使用

    firewalld(Dynamic Firewall Manager of Linux System,Linux系...

  • system() 函数

    system("dir /a / b >>name.txt");

  • Linux system()

    如果参数为elf文件,直接执行,如果为sh文件,直接执行。 如果为文本文件,读取内容执行。 场景 cat /pat...

  • Linux系统目录结构

    https://www.runoob.com/linux/linux-system-contents.html

  • Linux System Administration Solv

    下载地址:Linux System Administration Solve Real-life Linux Pr...

  • iptables 防火墙

    Linux System Environment iptables简介 iptables是Linux系统自带的采用...

网友评论

    本文标题:Linux system 函数

    本文链接:https://www.haomeiwen.com/subject/qjjgpttx.html