"从创建到管理,Linux进程编程是你掌握系统资源的金钥匙!"#Linux系统编程之进程【下】
- 前言
- 预备知识
- 一、 父进程等待子进程退出(一)
- 1.1 为啥要等待子进程退出
- 1.2 父进程等待子进程退出并收集退出状态
- 1.3 编程验证僵尸进程
- 1.3.1 程序代码
- 1.3.2 程序运行结果
- 1.4 主进程用于等待子进程wait函数介绍
- 1.4.1 man手册介绍
- 1.4.2 status参数介绍
- 1.5 程序验证wait的status参数为空起到防止僵尸进程
- 1.5.1 程序代码
- 1.5.2 程序运行结果
- 1.6 wait函数配合WEXITSTATUS(status)解析子进程终止状态
- 1.6.1 程序代码
- 1.6.2 程序运行结果
- 二、 父进程等待子进程退出(二)
- 2.1 wait和waitpid函数的区别
- 2.1.1 wait函数执行次序
- 2.1.2 waitpid函数介绍
- 2.1.3 wait和waitpid的区别
- 2.2 waitpid非阻塞编程实战
- 2.2.1 程序代码
- 2.2.2 程序运行结果
- 2.3 孤儿进程介绍
- 2.3.1 孤儿进程的定义
- 2.3.2 孤儿进程编程实战
- 2.4 Linux典型代码解析
- 三、 exec族函数
- 3.1 exec族函数详细介绍
- 3.2 利用execl函数实现操作当前根目录下的可执行文件
- 3.2.1 可执行文件程序代码
- 3.2.2 可执行文件程序运行结果
- 3.2.3 利用execl函数实现操作当前根目录下的可执行文件代码
- 3.2.4 利用execl函数实现操作当前根目录下的可执行文件代码运行结果
- 3.3 利用excel函数使用ls命令
- 3.3.1 ls命令目录查找
- 3.3.2 利用excel函数使用ls命令程序代码
- 3.3.3 利用excel函数使用ls命令程序运行结果
- 3.4 利用execl函数使用date命令
- 3.4.1 date命令介绍
- 3.4.2 利用execl函数使用date命令程序代码
- 3.4.3 利用execl函数使用date命令程序运行结果
- 3.5 echo $PATH命令介绍
- 3.5.1 echo $PATH命令执行结果
- 3.5.2 采用export PATH = $PATH + 路径修改环境变量
- 3.6 利用execlp函数使用命令ps
- 3.6.1 利用execlp函数使用命令ps程序代码
- 3.6.2 利用execlp函数使用命令ps程序运行结果
- 3.7 利用execv和execvp使用ps命令
- 3.7.1 利用execv和execvp使用ps命令程序代码
- 3.7.2 利用execv和execvp使用ps命令程序运行结果
- 3.8 使用exec族函数的作用
- 3.9 exec配合fork使用验证exec族函数的作用
- 3.9.1 实现的功能
- 3.9.2 不用exec族函数修改配置文件程序代码
- 3.9.3 不用exec族函数修改配置文件程序运行结果
- 3.9.4 使用exec族函数修改配置文件程序代码
- 3.9.5 使用exec族函数修改配置文件程序运行结果
- 四、 system函数
- 4.1 system函数详细介绍
- 4.2 使用system函数运行可执行文件system_text
- 4.2.1 system_text可执行文件程序代码
- 4.2.2 使用system函数运行可执行文件system_text程序代码
- 4.2.3 使用system函数运行可执行文件system_text程序运行结果
- 4.3 使用system函数修改配置文件TEST.config的内容
- 4.3.1 修改配置文件TEST.config程序代码
- 4.3.2 使用system函数修改配置文件TEST.config的内容程序代码
- 4.3.3 4.3.2 使用system函数修改配置文件TEST.config的内容程序运行结果
- 五、 popen函数
- 5.1 popen函数详细介绍
- 5.2 system和popen使用命令ps对比
- 5.2.1 system函数使用命令ps程序代码
- 5.2.2 system函数使用命令ps程序运行结果
- 5.2.3 popen函数使用命令ps程序代码
- 5.2.4 popen函数使用命令ps程序运行结果
- 结束语
前言
本篇博文将引领您继续Linux系统编程的深入探索,聚焦于进程管理的进阶篇(下篇)。我们将逐一揭开父进程如何优雅地等待子进程退出的面纱,分为两大章节详细阐述,确保您掌握这一关键技巧。随后,我们深入exec族函数的广阔天地,揭示它们如何替换当前进程的映像,执行新的程序。此外,还将介绍system函数与popen函数的独特魅力,展示它们在系统调用和管道通信中的灵活应用。无论您是Linux系统编程的初学者,还是希望深化理解的资深开发者,本博文都将为您提供不可或缺的知识和独到见解。在此,诚挚邀请您先点个赞,再细细品味这些精彩内容,让我们一同开启Linux系统编程的更多可能!
预备知识
一、C变量
二、基本输入输出
三、流程控制
四、函数
五、指针
六、字符串
七、Linux系统基本操作命令如mkdir,ls -l等。
八、计算内存知识:堆,栈等
如果以上知识不清楚,请自行学习后再来浏览。如果我有没例出的,请在评论区写一下。谢谢啦!
一、 父进程等待子进程退出(一)
1.1 为啥要等待子进程退出
如下图
1.2 父进程等待子进程退出并收集退出状态
如下图
1.3 编程验证僵尸进程
1.3.1 程序代码
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
pid_t fk;
//pid_t getpid(void);
int cnt = 0;
//pid_t fork(void);
fk = fork();
if(fk > 0)
{
父进程中没有等待子进程退出
while(1)
{
printf("This is the parent process,and its PID is %d\n",getpid());
sleep(1);
printf("cnt == %d\n",cnt);
}
}
else if(fk == 0)
{
while(1)
{
printf("This is a child process,and the child process is %d\n",getpid());
sleep(1);
cnt++;
if(cnt == 5)
{
exit(0);
}
}
}
return 0;
}
1.3.2 程序运行结果
1.4 主进程用于等待子进程wait函数介绍
1.4.1 man手册介绍
使用wait函数必须包含以下两个头文件
#include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int *status);
pid_t waitpid(pid_t pid, int *status, int options);
int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options);
1.4.2 status参数介绍
status参数:是一个整型数指针
非空:子进程退出状态放在它所指向的地址中。
空:不关心退出状态
status参数为空时,虽然不关心退出状态,但能起到防止僵尸进程。
1.5 程序验证wait的status参数为空起到防止僵尸进程
1.5.1 程序代码
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
pid_t fk;
//pid_t getpid(void);
int cnt = 0;
//pid_t fork(void);
fk = fork();
if(fk > 0)
{
while(1)
{
wait(NULL); 等待子进程结束
printf("This is the parent process,and its PID is %d\n",getpid());
sleep(1);
printf("cnt == %d\n",cnt);
}
}
else if(fk == 0)
{
while(1)
{
printf("This is a child process,and the child process is %d\n",getpid());
sleep(1);
cnt++;
if(cnt == 5)
{
exit(0);
}
}
}
return 0;
}
1.5.2 程序运行结果
如下图
1.6 wait函数配合WEXITSTATUS(status)解析子进程终止状态
1.6.1 程序代码
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
pid_t fk;
//pid_t getpid(void);
int cnt = 0;
int status = 10;
//pid_t fork(void);
fk = fork();
if(fk > 0)
{
while(1)
{
wait(&status); 等待子进程退出,退出状态返回给status
printf("This is the parent process,and its PID is %d\n",getpid());
sleep(1);
printf("status = %d\n",WEXITSTATUS(status));将status解析输出
}
}
else if(fk == 0)
{
while(1)
{
printf("This is a child process,and the child process is %d\n",getpid());
sleep(1);
cnt++;
if(cnt == 5)
{
exit(10);
}
}
}
return 0;
}
1.6.2 程序运行结果
如下图
二、 父进程等待子进程退出(二)
2.1 wait和waitpid函数的区别
2.1.1 wait函数执行次序
如果其所有子进程都还在运行,则阻塞。
如果一个子进程已终止,正等待父进程获取其终止状态,则取得该子进程的终止状态立即返回。
如果它没有任何子进程,则立即出错返回。
2.1.2 waitpid函数介绍
函数原型
pid_t waitpid(pid_t pid, int *status, int options);
第一个参数pid的介绍
第三个参数介绍
第二哥参数和wait一样,都是返回子进程退出状态。
2.1.3 wait和waitpid的区别
wait使调用者阻塞,waitpid有一个选项,可以使调用者不阻塞
2.2 waitpid非阻塞编程实战
2.2.1 程序代码
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
pid_t fk;
//pid_t getpid(void);
int cnt = 0;
int status = 10;
//pid_t fork(void);
fk = fork();
if(fk > 0)
{
while(1)
{
waitpid(fk,&status,WNOHANG); 非阻塞等待子进程结束
printf("This is the parent process,and its PID is %d\n",getpid());
sleep(1);
printf("status = %d\n",WEXITSTATUS(status));
}
}
else if(fk == 0)
{
while(1)
{
printf("This is a child process,and the child process is %d\n",getpid());
sleep(1);
cnt++;
if(cnt == 5)
{
exit(10);
}
}
}
return 0;
}
2.2.2 程序运行结果
如下图
2.3 孤儿进程介绍
2.3.1 孤儿进程的定义
父进程如果不等待子进程退出,在子进程之前就结束了自己的“生命”,此时子进程叫做孤儿进程。
Linux避免系统存在过多孤儿进程,init进程收留孤儿进程,变成孤儿进程的父进程,pid为1。
2.3.2 孤儿进程编程实战
程序代码
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
pid_t fk;
//pid_t getpid(void);
int cnt = 0;
int status = 10;
//pid_t fork(void);
fk = fork();
if(fk > 0)
{
printf("This is the parent process,and its PID is %d\n",getpid()); 父进程输出自己的进程标识符后就退出来,造成子进程变成孤儿进程。
}
else if(fk == 0)
{
while(1)
{
printf("This is a child process,and the child process is %d\n,Parent pid = %d\n",getpid(),getppid()); 输出子进程和父进程的进程标识符。
sleep(1);
cnt++;
if(cnt == 5)
{
exit(10);
}
}
}
return 0;
}
程序运行结果:如下图
2.4 Linux典型代码解析
如下图:
三、 exec族函数
3.1 exec族函数详细介绍
这里请参见大佬:"云英"的博文。
点击这里
3.2 利用execl函数实现操作当前根目录下的可执行文件
3.2.1 可执行文件程序代码
#include <stdio.h>
int main(int argc,char *argv[])
{
int i = 0;
for(i = 0; i < argc; i++)
{
printf("argv[%d]: %s\n",i,argv[i]);
}
return 0;
}
3.2.2 可执行文件程序运行结果
以下代码运行结果基于修改环境变量后
CLC@Embed_Learn:~/Linux_System_Programming/Linux_process_programming/07_Exec_family_functions$ ls
echoarg execl myls mypsp Process_programming2.c Process_programming4.c Process_programming6.c
echoarg.c mydate myps mypspp Process_programming3.c Process_programming5.c Process_programming.c
CLC@Embed_Learn:~/Linux_System_Programming/Linux_process_programming/07_Exec_family_functions$ echoarg aa bb
argv[0]: echoarg
argv[1]: aa
argv[2]: bb
3.2.3 利用execl函数实现操作当前根目录下的可执行文件代码
//文件execl.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
//函数原型:int execl(const char *path, const char *arg, ...);
int main(void)
{
printf("before execl\n");
if(execl("./echoarg","echoarg","abc",NULL) == -1) 利用execl函数打开当前目录下的可执行文件echoarg
{
printf("execl failed!\n");
perror("why"); 打开失败用perror函数输出错误原因
}
printf("after execl\n");
return 0;
}
3.2.4 利用execl函数实现操作当前根目录下的可执行文件代码运行结果
CLC@Embed_Learn:~/Linux_System_Programming/Linux_process_programming/07_Exec_family_functions$ gcc Process_programming.c -o execl
CLC@Embed_Learn:~/Linux_System_Programming/Linux_process_programming/07_Exec_family_functions$ execl
before execl
argv[0]: echoarg
argv[1]: abc
3.3 利用excel函数使用ls命令
3.3.1 ls命令目录查找
使用"whereis ls"命令查找
CLC@Embed_Learn:~/Linux_System_Programming/Linux_process_programming/07_Exec_family_functions$ whereis ls
ls: /bin/ls /usr/share/man/man1/ls.1.gz
以上查找结果为ls在目录:/bin/ls
3.3.2 利用excel函数使用ls命令程序代码
//文件execl.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
//函数原型:int execl(const char *path, const char *arg, ...);
int main(void)
{
printf("before execl\n");
if(execl("/bin/ls","ls",NULL,NULL) == -1)
{
printf("execl failed!\n");
perror("why");
}
printf("after execl\n");
return 0;
}
3.3.3 利用excel函数使用ls命令程序运行结果
CLC@Embed_Learn:~/Linux_System_Programming/Linux_process_programming/07_Exec_family_functions$ gcc Process_programming2.c -o myls
CLC@Embed_Learn:~/Linux_System_Programming/Linux_process_programming/07_Exec_family_functions$ myls
before execl
echoarg execl myls mypsp Process_programming2.c Process_programming4.c Process_programming6.c
echoarg.c mydate myps mypspp Process_programming3.c Process_programming5.c Process_programming.c
3.4 利用execl函数使用date命令
3.4.1 date命令介绍
date命令为获取系统当前时间信息。
3.4.2 利用execl函数使用date命令程序代码
代码只需要将利用excel函数使用ls命令程序代码打开路劲出修改一下即可
if(execl("/bin/ls","ls",NULL,NULL) == -1)
修改为:
if(execl("/bin/date","date",NULL,NULL) == -1)
3.4.3 利用execl函数使用date命令程序运行结果
CLC@Embed_Learn:~/Linux_System_Programming/Linux_process_programming/07_Exec_family_functions$ gcc Process_programming3.c -o mydate
CLC@Embed_Learn:~/Linux_System_Programming/Linux_process_programming/07_Exec_family_functions$ mydate
This get system date pro
2024年 08月 15日 星期四 22:57:10 CST
3.5 echo $PATH命令介绍
echo $PATH
命令的作用是显示当前用户的环境变量PATH
的值。PATH
环境变量是一个由冒号(:
)分隔的目录列表,这些目录是系统在查找可执行文件时所要搜索的目录。当你输入一个命令时,系统会按照PATH
环境变量中定义的目录顺序,在这些目录中查找是否存在该命令的可执行文件。
3.5.1 echo $PATH命令执行结果
CLC@Embed_Learn:~/Linux_System_Programming/Linux_process_programming/07_Exec_family_functions$ echo $PATH
/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/opt/FriendlyARM/toolschain/4.5.1/bin
3.5.2 采用export PATH = $PATH + 路径修改环境变量
CLC@Embed_Learn:~/Linux_System_Programming/Linux_process_programming/07_Exec_family_functions$ export PATH=$PATH:/home/CLC/Linux_System_Programming/Linux_process_programming/07_Exec_family_functions 修改环境变量路径为当前文件夹
CLC@Embed_Learn:~/Linux_System_Programming/Linux_process_programming/07_Exec_family_functions$ echo $PATH 查看修改后的结果
/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/opt/FriendlyARM/toolschain/4.5.1/bin:/home/CLC/Linux_System_Programming/Linux_process_programming/07_Exec_family_functions
3.6 利用execlp函数使用命令ps
3.6.1 利用execlp函数使用命令ps程序代码
//文件execl.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
//函数原型:int execl(const char *path, const char *arg, ...);
int main(void)
{
printf("Before execlp\n");
if(execlp("ps","ps",NULL,NULL) == -1) 多了一个p代表不用加路径就可以找到该命令
{
printf("execl failed!\n");
perror("why");
}
printf("after execl\n");
return 0;
}
3.6.2 利用execlp函数使用命令ps程序运行结果
CLC@Embed_Learn:~/Linux_System_Programming/Linux_process_programming/07_Exec_family_functions$ gcc Process_programming4.c -o mypsp
CLC@Embed_Learn:~/Linux_System_Programming/Linux_process_programming/07_Exec_family_functions$ mypsp
Before execlp
PID TTY TIME CMD
34509 pts/0 00:00:05 bash
47308 pts/0 00:00:00 vi
47812 pts/0 00:00:00 ps
3.7 利用execv和execvp使用ps命令
3.7.1 利用execv和execvp使用ps命令程序代码
这两个函数只是将
execlp("ps","ps",NULL,NULL)
换成
char *argv[] = {"ps",NULL,NULL};
execlp("ps",argv);
execv函数需要加路径,execvp不需要加路径。
3.7.2 利用execv和execvp使用ps命令程序运行结果
程序运行结果和利用execlp函数使用命令ps一样。
3.8 使用exec族函数的作用
一个进程执行一个不同的程序。这对shell是常见的情况。在这种情况下,子进程从fork返回后立即调用exec
3.9 exec配合fork使用验证exec族函数的作用
3.9.1 实现的功能
当父进程检测到输入为1的时候,创建子进程把配置文件的字段值修改掉。
3.9.2 不用exec族函数修改配置文件程序代码
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int main()
{
pid_t pid;
pid_t fk;
int data;
int fdSrc;
int size;
char *readBuf = NULL;
char *p = NULL;
//pid_t getpid(void);
printf("father : id = %d\n",getpid());
//pid_t fork(void);
while(1)
{
puts("Please enter a request");
scanf("%d",&data);
if(data == 1) 如果输入1创建子进程
{
fk = fork(); 创建进程
if(fk > 0)
{
wait(NULL); 主进程等待子进程退出返回退出状态
}
else if(fk == 0)
{
fdSrc = open("./TEST.config",O_RDWR); 打开配置文件
size =lseek(fdSrc,0,SEEK_END); 计算配置文件大小
lseek(fdSrc,0,SEEK_SET); 光标回归
readBuf = (char *)malloc(sizeof(char) * (size+1)); 给读缓冲区分配空间
read(fdSrc,readBuf,size +1); 读配置文件
printf("readBuf = \n%s\n",readBuf); 输出读到的配置文件
p = strstr(readBuf,"LENG = "); 在读到配置文件中查找修改项
if(p == NULL)
{
printf("Search failure!");
exit(-1); 查找失败退出
}
p = p + strlen("LENG = "); 查找成功让指针p偏移到修改位置
*p = '5'; 修改参数为字符5
lseek(fdSrc,0,SEEK_SET); 光标重新回归
write(fdSrc,readBuf,strlen(readBuf));将修改后的数据写入配置文件
lseek(fdSrc,0,SEEK_SET); 光标重新回归
read(fdSrc,readBuf,size +1); 读取已修改的配置文件
printf("readBuf = \n%s\n",readBuf); 输出已修改的配置文件
close(fdSrc); 关闭配置文件
exit(0); 退出子进程
}
}
else if(data==0) 如果输入0,退出父进程
{
return 0;
}
else
{
puts("Wait for input!");
}
}
}
3.9.3 不用exec族函数修改配置文件程序运行结果
如下图
3.9.4 使用exec族函数修改配置文件程序代码
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int main()
{
pid_t pid;
pid_t fk;
int data;
int fdSrc;
int size;
char *readBuf = NULL;
char *p = NULL;
//pid_t getpid(void);
printf("father : id = %d\n",getpid());
//pid_t fork(void);
while(1)
{
puts("Please enter a request");
scanf("%d",&data);
if(data == 1)
{
fk = fork();
if(fk > 0)
{
wait(NULL);
}
else if(fk == 0)
{
execl("./editcon","editcon","TEST.config",NULL); 使用exec族函数在子进程中调用没有使用exec族函数修改配置文件生成的可执行文件
}
}
else if(data == 0)
{
return 0;
}
else
{
puts("Wait for input!");
}
}
}
3.9.5 使用exec族函数修改配置文件程序运行结果
如下图
四、 system函数
4.1 system函数详细介绍
这里参见大佬:"南哥的天下"的博文
点击这里
4.2 使用system函数运行可执行文件system_text
4.2.1 system_text可执行文件程序代码
#include <stdio.h>
int main()
{
printf("This is system text!\n");
return 0;
}
4.2.2 使用system函数运行可执行文件system_text程序代码
//文件execl.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
//函数原型:int execl(const char *path, const char *arg, ...);
int main(void)
{
printf("before execl\n");
if(system("./system_text") == -1) 使用system函数运行可执行文件system_text
{
printf("execl failed!\n");
perror("why");
}
printf("after execl\n");
return 0;
}
4.2.3 使用system函数运行可执行文件system_text程序运行结果
CLC@Embed_Learn:~/Linux_System_Programming/Linux_process_programming/08_System_function$ gcc Process_programming.c -o mysystem
CLC@Embed_Learn:~/Linux_System_Programming/Linux_process_programming/08_System_function$ ./mysystem
before execl
This is system text!
after execl
4.3 使用system函数修改配置文件TEST.config的内容
4.3.1 修改配置文件TEST.config程序代码
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int main(int argc,char **argv)
{
int fdSrc;
int size;
char *readBuf = NULL;
char *p = NULL;
if(argc < 2)
{
printf("Program error!\n");
exit(-1);
}
fdSrc = open(argv[1],O_RDWR);
size =lseek(fdSrc,0,SEEK_END);
lseek(fdSrc,0,SEEK_SET);
readBuf = (char *)malloc(sizeof(char) * (size+1));
read(fdSrc,readBuf,size +1);
printf("readBuf = \n%s\n",readBuf);
p = strstr(readBuf,"LENG = ");
if(p == NULL)
{
printf("Search failure!");
exit(-1);
}
p = p + strlen("LENG = ");
*p = '5';
lseek(fdSrc,0,SEEK_SET);
write(fdSrc,readBuf,strlen(readBuf));
lseek(fdSrc,0,SEEK_SET);
read(fdSrc,readBuf,size +1);
printf("readBuf = \n%s\n",readBuf);
close(fdSrc);
return 0;
}
4.3.2 使用system函数修改配置文件TEST.config的内容程序代码
//文件execl.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
//函数原型:int execl(const char *path, const char *arg, ...);
int main(void)
{
printf("before execl\n");
if(system("./myedit TEST.config") == -1) 使用system函数运行myedit可执行文件修改TEST.config文件内容
{
printf("execl failed!\n");
perror("why");
}
printf("after execl\n");
return 0;
}
4.3.3 4.3.2 使用system函数修改配置文件TEST.config的内容程序运行结果
CLC@Embed_Learn:~/Linux_System_Programming/Linux_process_programming/08_System_function$ gcc Process_programming2.c -o mysystem2
CLC@Embed_Learn:~/Linux_System_Programming/Linux_process_programming/08_System_function$ ./mysystem2
before execl
readBuf =
SPEED = 3
LENG = 9
SCORE = 9
LEVEL = 9
readBuf =
SPEED = 3
LENG = 5
SCORE = 9
LEVEL = 9
after execl
五、 popen函数
5.1 popen函数详细介绍
这里参见大佬:"libinbin_1014"的博文
点击这里
以下是我的简易原理示意图。
5.2 system和popen使用命令ps对比
5.2.1 system函数使用命令ps程序代码
//文件execl.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
//函数原型:int execl(const char *path, const char *arg, ...);
int main(void)
{
printf("before execl\n");
if(system("ps") == -1) system函数使用命令ps
{
printf("execl failed!\n");
perror("why");
}
printf("after execl\n");
return 0;
}
5.2.2 system函数使用命令ps程序运行结果
这是在终端输出
CLC@Embed_Learn:~/Linux_System_Programming/Linux_process_programming/09_Popen_function$ gcc Process_programming.c -o mysystem
CLC@Embed_Learn:~/Linux_System_Programming/Linux_process_programming/09_Popen_function$ ./mysystem
before execl
PID TTY TIME CMD
34509 pts/0 00:00:07 bash
47308 pts/0 00:00:00 vi
48087 pts/0 00:00:00 vi
49330 pts/0 00:00:00 mysystem
49331 pts/0 00:00:00 sh
49332 pts/0 00:00:00 ps
after execl
5.2.3 popen函数使用命令ps程序代码
//文件execl.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
//函数原型:int execl(const char *path, const char *arg, ...);
int main(void)
{
char result[1024] = {0};
FILE *fp = NULL;
int n_read = 0;
fp = popen("ps","r"); popen函数使用命令ps返回值给FILE *fp;
//size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
n_read = fread(result,1,1024,fp); 读取open使用ps命令输出结果
printf("n_read = %d\n,This read data = \n%s\n",n_read,result);输出读取open使用ps命令的结果
return 0;
}
5.2.4 popen函数使用命令ps程序运行结果
这是在输出result字符串
CLC@Embed_Learn:~/Linux_System_Programming/Linux_process_programming/09_Popen_function$ gcc Process_programming2.c -o mypopen
CLC@Embed_Learn:~/Linux_System_Programming/Linux_process_programming/09_Popen_function$ ./mypopen n_read = 197
,This read data =
PID TTY TIME CMD
34509 pts/0 00:00:07 bash
47308 pts/0 00:00:00 vi
48087 pts/0 00:00:00 vi
49451 pts/0 00:00:00 mypopen
49452 pts/0 00:00:00 sh
49453 pts/0 00:00:00 ps
结束语
非常感谢您的耐心阅读!在您即将离开之际,如果您觉得内容有所收获或启发,不妨动动手指,点个赞再走,这将是对我莫大的鼓励和支持。衷心感谢您的点赞与关注,期待未来能继续为您带来更多有价值的内容!谢谢您!