popen与system函数

本文深入探讨了Linux中popen与system函数的使用方法及原理。popen通过管道与shell命令进行通信,提供了读写功能;system则用于执行shell命令,并通过waitpid处理僵尸进程。文章还提供了代码示例,帮助读者理解如何在实际应用中调用这两个函数。

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

popen与system

在linux中我们可以通过system()来执行一个shell命令,popen()也是执行shell命令并且通过管道和shell命令进行通信。
system()、popen()给我们处理了fork、exec、waitpid等一系列的处理流程,让我们只需要关注最后的返回结果(函数的返回值)即可。

popen函数

函数介绍

在这里插入图片描述
(1)popen()会调用fork()产生子进程,然后从子进程中调用/bin/sh -c来执行参数command的指令。
(2)参数type可使用“r”代表读取,“w”代表写入。根据此type值,popen()会建立管道连到子进程的标准输出设备或标准输入设备,然后返回一个文件指针。随后进程便可利用此文件指针来读取子进程的输出设备或是写入到子进程的标准输入设备中。
(3)此外,所有使用文件指针(FILE*)操作的函数也都可以使用,除了fclose()以外。
(4)如果 type 为 r,那么调用进程读进 command 的标准输出。
如果 type 为 w,那么调用进程写到 command 的标准输入。
返回值: 若成功则返回文件指针,否则返回NULL,错误原因存于errno中。
注意: popen()会继承环境变量。

模拟实现

    #include<stdio.h>
    #include<stdlib.h>
    int main()
    {
         FILE *fp;
        char buffer[80];
        fp = popen("cat /etc/passwd", "r");
        if(fp == NULL)
        {
        	printf("open file error");
        	return -1;
        }
        fgets(buffer, sizeof(buffer), fp);
        printf("%s", buffer);
        pclose(fp);
        return 0
    }

#include “stdio.h”
#include “stdlib.h”
int main()
{
FILE *fp;
char buf[200] = {0};
if((fp = popen(“cat > test1″, “w”)) == NULL) {
perror(“Fail to popen\n”);
exit(1);
}
fwrite(“Read pipe successfully !, 1, sizeof(“Read pipe successfully !), fp);
pclose(fp);
return 0;
}

system函数

函数介绍

在这里插入图片描述
system()函数先fork一个子进程,在这个子进程中调用/bin/sh -c来执行command指定的命令。/bin/sh在系统中一般是个软链接,指向dash或者bash等常用的shell,-c选项是告诉shell从字符串command中读取要执行的命令(shell将扩展command中的任何特殊字符)。父进程则调用waitpid()函数来为变成僵尸的子进程收尸,获得其结束状态,然后将这个结束状态返回给system()函数的调用者。
返回值
(1)当参数command是NULL的时候 在参数为NULL的情况下,system函数的返回值很简单明了,只有0和1。 返回1,表明系统的命令处理程序,即/bin/sh是可用的。 相反,如果命令处理程序不可用,则返回0。
(2)当参数command不是NULL的时候当参数不为NULL的时候,根据APUE这里可以分为以下三种情况:
1)如果fork等系统调用失败,或者waitpid函数发生除EINTR外的错误时,system返回-1
2)一切致使execl失败的情况下,system返回127
3)除此之外,system返回/bin/sh的终止状态

模拟实现
int system(const char * cmdstring)
{
pid_t pid;
int status;

if(cmdstring == NULL){

     return (1);
}


if((pid = fork())<0){

        status = -1;
}
else if(pid == 0){
    execl("/bin/sh", "sh", "-c", cmdstring, (char *)0);
    -exit(127); //子进程正常执行则不会执行此语句
    }
else{
        while(waitpid(pid, &status, 0) < 0){
            if(errno != EINTER){
                status = -1;
                break;
            }
        }
    }
    return status;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值