目录
popen是什么意思?
Linux中system()函数与popen()函数 (*)
linux system()函数完全解密
linux popen()函数完全解密
C 语言popen函数,逐行读取shell命令内容
基于管道的popen和pclose函数
popen() 使用举例 (转载)
popen函数 Qt
-------------------------------------------------------
https://blog.csdn.net/ken2232/article/details/130316198
QString::toWCharArray 与 宽字符路径、空格 (测试OK)(***)
------------------------------
比较:
popen():popen(命令, "r"),直接支持宽字符。宽字符文件路径,与_wsystem相比,使用popen似乎最简单?
_wsystem():_wsystem(L“宽字符串命令”),支持宽字符。为 win OS 下的app,linux不能用?!
system():只支持 latin1。
==================================
学习笔记——popen()函数详解
https://blog.csdn.net/qq_44333320/article/details/124875059
popen()函数
引用度娘说的:
popen() 函数通过创建一个管道,调用 fork 产生一个子进程,执行一个 shell 以运行命令来开启一个进程。
这个进程必须由 pclose() 函数关闭,而不是 fclose() 函数。pclose() 函数关闭标准 I/O 流,等待命令执行结束,然后返回 shell 的终止状态。如果 shell 不能被执行,则 pclose() 返回的终止状态与 shell 已执行 exit 一样。
也就是,popen创建管道,执行shell命令将文件流中的某些数据读出
看看man手册
NAME
popen, pclose - pipe stream to or from a processSYNOPSIS
#include <stdio.h>//头文件FILE *popen(const char *command, const char *type);//原型
参数说明:
command: 是一个指向以 NULL 结束的 shell 命令字符串的指针。命令将被传到 bin/sh 并使用 -c 标志,shell 将执行这个命令,比如sh -c ls
type: 只能是读或者写中的一种,得到的返回值(标准 I/O 流)也具有和 type 相应的只读或只写类型。如果 type 是 “r” 则文件指针连接到 command 的标准输出;如果 type 是 “w” 则文件指针连接到 command 的标准输入。
返回值:
如果调用 fork() 或 pipe() 失败,或者不能分配内存将返回NULL,否则返回一个读或者打开文件的指针。
————————————————
版权声明:本文为CSDN博主「石子君」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_44333320/article/details/124875059
system(3) — Linux manual page
https://man7.org/linux/man-pages/man3/system.3.html
SYNOPSIS
#include <stdlib.h>
int system(const char *command);
=======================
popen是什么意思?
popen == opens a process == process opens ??
popen
DESCRIPTION
The popen() function opens a process by creating a pipe, forking, and invoking the shell. Since a pipe is by definition unidirectional, the type argument may specify only reading or writing, not both; the resulting stream is correspondingly read- only or write-only.
https://www.man7.org/linux/man-pages/man3/popen.3.html
popen函数 Qt
pclose(fp); //记得释放资源
popen函数使用示例
环境:CentOS7.6 Qt 5.9.4
QSring strCmd = "cat /proc/cpuinfo |grep MHz|uniq\n";
FILE* fp = popen(strCmd.toLocal8Bit().data(), "r");
if (nullptr != fp)
{
char buf[1024] = {0};
char result[2000] = {0};
while (fgets(buf, sizeof(buf), fp))
{
strcat(result, buf);
if (strlen(result) > sizeof(buf))
{
break;
}
}
pclose(fp); //记得释放资源
fp = nullptr;
//result即为执行终端命令“cat /proc/cpuinfo |grep MHz|uniq”得到的结果
//后续可对result 进行其他处理
}
popen() 使用举例 (转载)
popen() 使用举例 (转载)_diedie4488的博客-CSDN博客
函数原型:
#include “stdio.h”
FILE *popen( const char* command, const char* mode )
参数说明:
command: 是一个指向以 NULL 结束的 shell 命令字符串的指针。这行命令将被传到 bin/sh 并使用 -c 标志,shell 将执行这个命令。
mode: 只能是读或者写中的一种,得到的返回值(标准 I/O 流)也具有和 type 相应的只读或只写类型。如果 type 是 “r” 则文件指针连接到 command 的标准输出;如果 type 是 “w” 则文件指针连接到 command 的标准输入。
返回值:
如果调用成功,则返回一个读或者打开文件的指针,如果失败,返回NULL,具体错误要根据errno判断
int pclose (FILE* stream)
参数说明:
stream:popen返回的文件指针
返回值:
如果调用失败,返回 -1
作用:
popen() 函数用于创建一个管道:其内部实现为调用 fork 产生一个子进程,执行一个 shell 以运行命令来开启一个进程这个进程必须由 pclose() 函数关闭。
基于管道的popen和pclose函数
基于管道的popen和pclose函数_pclose return 256_路飞大大的博客-CSDN博客
标准I/O函数库提供了popen函数,它启动另外一个进程去执行一个shell命令行。
这里我们称调用popen的进程为父进程,由popen启动的进程称为子进程。
popen函数还创建一个管道用于父子进程间通信。子进程要么从管道读信息,要么向管道写信息,至于是读还是写取决于父进程调用popen时传递的参数。下在给出popen、pclose的定义:
C 语言popen函数,逐行读取shell命令内容
1. popen()函数
头文件:#include <stdio.h>
函数原型:FILE * popen(const char * command, const char * type);
关闭文件流:int pclose(FILE * stream);
函数popen 先执行fork,然后调用exec以执行cmd,并且返回一个标准I/O文件指针。
cmd是一个包含shell命令的字符串指针(以NULL结束字符结尾);
如果type是"r",则文件指针连接到cmd的标准输出;
如果type是"w",则文件指针连接到cmd的标准输入。
2. 描述
popen() 函数用创建管道的方式启动一个进程, 并调用 shell. 因为管道是被定义成单向的, 所以type参数只能定义成只读或者只写, 不能是两者同时, 结果流也相应的是只读或者只写.
command 参数是一个字符串指针, 指向的是 一个以 null 结束符结尾的字符串, 这个字符串包含一个 shell 命令. 这个命令被送到 /bin/sh 以 -c 参数执行, 即由 shell 来执行. type 参数也是一个 指向以 null 结束符结尾的字符串的指针, 这个字符串必须是 'r' 或者 'w’ 来指明是读还是写.
popen() 函数的返回值是一个普通的标准I/O流, 它只能用 pclose() 函数来关闭, 而不是 fclose() 函数.
注意, popen 函数的输出流默认是被全缓冲的;pclose 函数等待相关的进程结束并返回一个 command 命令的退出状态, 就像 wait4 函数 一样
————————————————
版权声明:本文为CSDN博主「smartvxworks-V2」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/smartvxworks/article/details/128957587
linux popen()函数完全解密
https://zhuanlan.zhihu.com/p/457974696
linux system()函数完全解密
https://zhuanlan.zhihu.com/p/457019360
为什么很多网友和技术大佬都推荐使用它替代system()来使用呢?
====================================
Linux中system()函数与popen()函数 (*)
http://laihaodong.cn/2061.html
1. system()
程序可以通过调用 system() 函数来执行任意的shell命令。同样这个Shell命令执行的输出会打印在终端上。\
#include <stdlib.h>
int system(const char* command);
C
system()
库函数通过fork出一个子进程,并且让子进程通过execl()
程序替换来执行对应的 shell 命令。问题是替换成什么程序可以执行shell命令呢?答案是 /bin
目录下的sh
程序。sh -c command
即可执行指定的命令。sh 其实就是一个shell程序,在我的系统中 sh 是一个指向 dash 的软链接,所以system()
的真正执行步骤应该是:调用system()
,函数内部创建了一个子进程并替换成 shell 程序,而 shell 程序执行一条命令的步骤同样是创建一个子进程,并让子进程替换成需要执行的 command,所以可以看到system()
运行期间总共存在三个进程。下图展现了用system()
执行sleep命令的步骤:
system()
当命令执行完毕才会返回,也就是阻塞函数。
在命令执行期间,SIGCHLD信号将被阻塞,SIGINT和SIGQUIT信号将被忽略。
如果 command 为NULL,则system()
返回一个表示当前系统是否有可用shell的状态。
2. 基本的 system() 实现
先按照文档的描述来实现一个简单的system()
函数,这其实就是对Linux编程的基本知识如创建子进程、进程等待、进程替换的一个综合运用。
int my_system(const char* command) {
pid_t pid = fork();
int status;
switch(pid) {
case -1:
return -1;
case 0: // child
execl("/bin/sh", "sh", "-c", command, NULL);
exit(-1); // execl error
default: // parent
waitpid(pid, &status, 0);
return status;
}
}
C
3. popen() : 通过管道与Shell命令进行通信
popen()
与system()
的功能类似,同样是执行一条Shell命令。但popen()
使用了管道来读取Shell命令的输出或者是通过管道来给Shell命令传递输入。
#include <stdio.h>
FILE* popen(const char* command, const char* mode);
int pclose(FILE* stream);
C
popen()
函数创建了一个管道,然后创建一个子进程来执行Shell,而Shell同样需要创建一个子进程来执行指定的Shell命令。这个过程类似于system()
。mode 参数是一个字符串,它确定函数的调用者是从管道中读取 Shell 命令的输出(mode为 r ),还是通过管道给Shell命令传递输入(mode为 w )。(由于单个管道只支持单向信息传输,所以必须在创建管道之前就确定数据传输方向)。下图展示了两种mode取值的不同之处:
popen()
返回了该管道的操作句柄,即一个文件流指针,函数调用者可以通过这个操作句柄来和Shell命令进行通信。这也点出了popen()
与system()
的不同之处,即system()
是一个阻塞函数,Shell命令执行完成之前不会返回,用户通过终端与Shell命令交互。而popen()
是一个非阻塞函数,它在建立一个子进程并执行程序替换sh -c command
之后会立刻返回,而不等待Shell程序的终止。用户通过主程序与Shell命令进行通信。即可以总结为popen()
的调用进程与Shell命令进程是并行执行的。
由于使用的是管道,所以与 pipe 创建出的管道有相同的读写特性,即管道写端关闭后尝试读会返回0,管道读端关闭后尝试写会受到 SIGPIPE 信号而被杀死。
一旦 I/O 结束后可以使用pclose()
函数关闭管道,并且该函数会等待Shell程序终止才返回。而pclose()
的返回值为Shell进程的终止状态,即 wait 所得到的状态。
4. 基本的popen() 实现
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
FILE* my_popen(const char* command, const char* type) {
FILE* fp;
// if type is invalid
if((type[0] != 'w' && type[0] != 'r') || type[1] != '\0') {
return NULL;
}
int pipefd[2];
pipe(pipefd);
pid_t pid = fork();
switch(pid) {
case -1:
perror("fork error");
exit(0);
case 0: // child
if(type[0] == 'w') {
close(pipefd[1]);
dup2(pipefd[0], STDIN_FILENO);
close(pipefd[0]); // close extra read end
}
else if(type[0] == 'r') {
close(pipefd[0]);
dup2(pipefd[1], STDOUT_FILENO);
close(pipefd[1]); // close extra write end
}
execl("/bin/sh", "sh", "-c", command, NULL);
exit(-1);
default: // parent
if(type[0] == 'r') {
close(pipefd[1]);
fp = fdopen(pipefd[0], type);
}
else {
close(pipefd[0]);
fp = fdopen(pipefd[1], type);
}
return fp;
}
}