C语言实现unix系统调用system

本文详细介绍了C语言中的system函数,解释了它是如何通过/bin/sh -c执行命令,并在dash环境下运行。文章还探讨了system函数如何处理SIGCHLD、SIGINT和SIGQUIT信号,并提供了一个简单的实现示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

system系统函数的功能是在c语言调用运行bash脚本的,只要是在bash可以运行的脚本,放在system函数中都可以运行.

其中命令行下的脚本是运行在当前bash环境下的.而对于脚本(.sh文件)或者system调用,是需要重新启动一个进程bash.我电脑ubuntu14.04默认启动的是/bin/sh,链接到的是dash,这个轻量级的bash.到底是bash还是dash,可以通过下面的命令查看.

这里写图片描述

dash和bash

dash和bash都是遵循posix标准的系统应用,dash相比于bash有更快的运行速度.关于详细介绍可以参看下面几篇介绍.
大概介绍:https://www.cyberciti.biz/faq/debian-ubuntu-linux-binbash-vs-bindash-vs-binshshell/
详细介绍:https://wiki.ubuntu.com/DashAsBinSh
性能对比:https://wiki.debian.org/DebianEeePC/Dash

基于性能的考虑,/bin/sh是调用dash,所以在运行($sh *.sh)命令的时候,是调用dash,作为其运行环境.而对于system函数也是调用/bin/sh.也就是在dash的环境下运行命令.

system(cmdstring)

system函数

概述

system函数通过/bin/sh-c执行命令行命令,在执行过程中,system函数会阻塞SIGCHLD信号(等待子进程返回,否则返回值会出现错误),会忽略SIGINT和SIGQUIT信号.

system() executes a command specified in command by calling /bin/sh -c command, and returns after the command has been completed.During execution of the command, SIGCHLD will be blocked, and SIGINT and SIGQUIT will be ignored.

简单实现

system函数主要就是通过在子进程中执行/bin/sh -c cmdstring实现,主要涉及的是三个函数,fork,execl和waitpid
1.fork();创建一个子进程,如果创建失败,返回值为-1;
2.execl(“/bin/sh”,”sh”,”-c”,cmdstring,(char*)0);执行失败返回127.
3.如果三个函数都执行成功,那么函数的返回值为0;

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<signal.h>
int main(int argc,char*argv[]){

    int status =  mysystem("ls -l");
    printf("status = %d\n",status);
    return 0;
}
int mysystem(const char *cmdstring){


    int status;
    int pid = fork();

    if(pid==-1){
        return -1;
    }

    if(pid==0){

       //system("ps");
       int e_status;
       if((e_status = execl("/bin/sh","sh","-c",cmdstring,(char*)0))<0){
           printf("hello world %d\n",e_status);
           exit(127);
       }

       //Even though execl excute successly,this can not be excuted.
       //printf("hello world %d",e_status);
    }

    printf("the pid of child %d\n",pid);

    waitpid(pid,&status,0);
    return status;
}

system函数默认是忽略SIGINT(ctrl+c),SIGQUIT(ctrl+)信号的,上述的实现并没有涉及忽略这两个信号.因为不怎么熟悉如何忽略信号,之后再来补上,贴一篇比较完整的博客:http://blog.youkuaiyun.com/dlutbrucezhang/article/details/8914772

可以通过下面的代码测试这两个信号是被忽略的.

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int main(int argc,char *argv[]){
    while(1){
        system("ps");
    }
    return 0;
}

发现,陷入死循环,ctrl+c和ctrl+\都无法停止.说明两个信号都被忽略了.ctrl+z挂起,可以正常停止.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值