• linux--进程--system与popen函数


    1.system

    1. #include
    2. int system(const char *command);

    返回值:

            成功,则返回进程的状态值;不能源码execl函数,返回127;失败返回-1;

            不能成功运行分析文章:linux下system函数详解_linux system_遥_望的博客-CSDN博客

    linux系统下,system函数是execl函数的封装版

    popen()函数较于system()函数的优势在于使用简单,popen()函数只返回两个值:成功 /失败

    源码:

    1. #include
    2. #include
    3. #include
    4. #include
    5. int system(const char * cmdstring)
    6. {
    7. pid_t pid;
    8. int status;
    9. if(cmdstring == NULL){
    10. return (1);
    11. }
    12. if((pid = fork())<0){
    13. status = -1;
    14. }
    15. else if(pid == 0){
    16. execl("/bin/sh", "sh", "-c", cmdstring, (char *)0);
    17. -exit(127); //子进程正常执行则不会执行此语句
    18. }
    19. else{
    20. while(waitpid(pid, &status, 0) < 0){
    21. if(errno != EINTER){
    22. status = -1;
    23. break;
    24. }
    25. }
    26. }
    27. return status;
    28. }

    在linux系统下,system函数是execl函数的封装版
    文中的 "sh -c ps"和我们所使用的"ps"是完全等价的

    例子代码:

    1. #include
    2. #include
    3. int main()
    4. {
    5. system("ps");
    6. printf("\n");
    7. }

    直接运行ps指令;

    运行文件:

    1. #include
    2. int main(int argc,char *argv[])
    3. {
    4. int i;
    5. for(i=0;i
    6. printf("argv[%d]:%s\n",i,argv[i]);
    7. }
    8. return 0;
    9. }

    system运行:

    1. #include
    2. #include
    3. int main()
    4. {
    5. system("./test aa bb cc dd");
    6. printf("\n");
    7. }

    结果:

        argv[0]:./test  //程序地址
        argv[1]:aa //以下为程序参数
        argv[2]:bb
        argv[3]:cc
        argv[4]:dd

    还可以运行子进程中的其他程序:

    在Linux文件编程中

    写一个TEST.config文件:

    SPEED=5
    LENG=1
    SCORE=90
    LEVEL=95

    对TEST.config文件内容进行修改,将LENG=1,改成LENG=5

    代码:

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8.  
    9. int main(int argc,char **argv)
    10. {
    11.     int fdsrc;
    12.     char *readbuf=NULL;
    13.     
    14.     if(argc!=2){
    15.         printf("pararm error\n");
    16.         exit(-1);//tuichugaichengxu
    17.     }
    18.     
    19.     //打开文件,将文件复制到readbuf中
    20.     fdsrc=open(argv[1],O_RDWR);
    21.     int size=lseek(fdsrc,0,SEEK_END);
    22.     lseek(fdsrc,0,SEEK_SET);
    23.  
    24.     readbuf=(char *)malloc(sizeof(char)*size+8);
    25.     int n_read=read(fdsrc,readbuf,size);
    26.  
    27.     //找到readbuf中LENG=中的位置,将位置移动到1,替换为5
    28.     char *p=strstr(readbuf,"LENG=");
    29.     if(p==NULL){
    30.         printf("not found\n");
    31.         exit(-1);
    32.     }
    33.     
    34.     p=p+strlen("LENG=");
    35.     *p='5';
    36.  
    37.     //移动光标到文件头,重新将readbuf中的内容写入到打开的文件中
    38.     lseek(fdsrc,0,SEEK_SET);
    39.     int n_write=write(fdsrc,readbuf,strlen(readbuf));
    40.  
    41.  
    42.     close(fdsrc);
    43.     return 0;
    44. }


    编译:gcc demo13.c

    运行:./a.out TEST.config

    运行结果为:

    SPEED=5
    LENG=5
    SCORE=90
    LEVEL=95

    system运用:

    将上述代码编译为./changedata

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. int main()
    9. {
    10. pid_t pid;
    11. int data=10;
    12. while(1){
    13. printf("please input a data\n");
    14. scanf("%d",&data);
    15. if(data==1){
    16. pid=fork();
    17. if(pid>0){
    18. wait(NULL);
    19. }
    20. if(pid==0){
    21. // execl("./changedata","changedata","config.txt",NULL);
    22. system("./changedata config.txt");
    23. exit(0);
    24. }
    25. }
    26. else{
    27. printf("wait,do nothing\n");
    28. }
    29. }
    30. return 0;
    31. }

    cat config.txt

    能够发现LENG=1变成了LENG=5

    要注意的是,system运行完后,父进程还会继续向下运行,这点与execl函数不同。

    2.popen函数

    popen的使用:

    #include
     
    FILE *popen(const chat *command, const char *type);
    int pclose(FILE *stream);

     command:是一个指向以NULL结束的shell命令字符串的指针。

    type:只能是读或写的其中一种r/w

    无法获得system的值,需要使用popen
     

    代码:

    1. #include
    2. int main()
    3. {
    4. char ret[500]={0};
    5. FILE *fp;
    6. fp = popen("ps","r");
    7. int n_read = fread(ret,1,1024,fp);
    8. printf("read ret = %d byte\n ret =\n %s\n",n_read,ret);
    9. return 0;
    10. }

    结果:

    当使用system时,ret的值无法读出,用popen函数;

  • 相关阅读:
    Vue3动态显示时间
    物联网开发笔记(41)- 使用Micropython开发ESP32开发板之控制4*4矩阵键盘
    浏览器解码过程分析
    OwnCloud个人云盘搭建方法
    从传统到智能化:汽车内部通信的安全挑战与SecOC解决方案
    6.jQuery中的Ajax上传文件
    Docker搭建runcher教程
    重写代码实现Flink连接Redis集群(Java版,解决Flink无法连接私有IP Redis集群问题)
    Win11应用商店下载的软件怎么移到桌面
    CI2454集成2.4G收发SOC【遥控;灯具;玩具】技术开发资料
  • 原文地址:https://blog.csdn.net/Herry_z/article/details/132769275