当前位置:网站首页 > 技术博客 > 正文

py pop函数



自己给自己挖的坑(bug),终究是要自己填上的~~

先简单的解释一下popen函数吧~

popen():进程I/O函数,与pclose函数一起使用。

1.1函数定义:

1.2包含头文件:

#include <stdio.h>

1.3函数说明:

  • popen() 函数通过创建一个管道,调用 fork 产生一个子进程,执行一个 shell 以运行命令来开启一个进程。这个进程必须由 pclose() 函数关闭,而不是 fclose() 函数。pclose() 函数关闭标准 I/O 流,等待命令执行结束,然后返回 shell 的终止状态。如果 shell 不能被执行,则 pclose() 返回的终止状态与 shell 已执行 exit 一样。
  • type 参数只能是读或者写中的一种,得到的返回值(标准 I/O 流)也具有和 type 相应的只读或只写类型。如果 type 是 “r” 则文件指针连接到 command 的标准输出;如果 type 是 “w” 则文件指针连接到 command 的标准输入
  • command 参数是一个指向以 NULL 结束的 shell 命令字符串的指针。这行命令将被传到 bin/sh 并使用-c 标志,shell 将执行这个命令。
  • popen 的返回值是个标准 I/O 流,必须由 pclose 来终止。前面提到这个流是单向的。所以向这个流写内容相当于写入该命令的标准输入;命令的标准输出和调用 popen 的进程相同。与之相反的,从流中读数据相当于读取命令的标准输出;命令的标准输入和调用 popen 的进程相同。

1.4函数返回值

​ 如果调用 fork() 或 pipe() 失败,或者不能分配内存将返回NULL,否则返回标准 I/O 流

1.5 函数错误状态

popen 没有为内存分配失败设置 errno 值。

​ 如果调用 fork() 或 pipe() 时出现错误,errno 被设为相应的错误类型。

​ 如果 type 参数不合法,errno将返回EINVAL。

百度百科:https://baike.baidu.com/item/popen/?fr=aladdin

下面放一个简单的代码:

 

运行结果:

执行 ls -l popen.c 结果如下:

 

执行 ifconfig eth0 结果如下:

 

这里可以看到,结果是符合我们预期的

为什么我会在这里放一个 ifconfig eth0 的命令呢?我自己给自己挖的bug就在这了 ╮(╯▽╰)╭

因为在封装一个函数时,功能是判断某个网卡是否存在?然后就需要用到这个命令嘞

让我们来看一下,bug到底是什么

还是上面那个示例代码,但是将那个执行的命令改一下:

执行 ifconfig bughere 结果如下:

 

这里我们可以看到,它确实有输出,输出就是bughere:…

但是发现什么问题没有?read ret 0 byte , 并没有读到数据,而且这两个输出的顺序好像不太一样~~~

让我们再看一组结果:

执行 ls -l popenbug2 结果如下:

 

又是这样让人难以接受的结果

为什么会这样呢???

一开始,我实在不能理解,也不相信,难道读到的数据真的是0个字节嘛???

于是我想到把该(ret)空间的首地址的数据打印一下看看

 

这个结果彻底打消了我的念头 ≧ ﹏ ≦

popen确实没有获取到任何数据

于是我只能从popen函数本身出发,去反复检查关于popen函数的定义,返回值等等。。。

如果调用 fork() 或 pipe() 失败,或者不能分配内存将返回NULL,否则返回标准 I/O 流

一开始,我并没有完全理解这句话,我天真的以为:执行的命令有输出,就是fork()成功调用了,理应返回标准I/O流,但是事与愿违。。。

最后我想到了检查popen执行的命令在命令行执行的返回值

在这里插入图片描述

​ 然后还真让我发现了问题,凡是带有No、not found等等类型字样的(文件找不到啊、网卡不存在啊),也就是你请求的命令,没有得到你想要的结果的(命令输错,内容不存在),这些命令的返回值都是大于零的,而命令得到正确回复的,返回值都是零。

​ 而且最终的结果也是命令行返回值不是0的,都无法被popen函数获取到I/O流,带着这个收获,又去琢磨了一番popen函数的相关定义和返回值说明,终于是琢磨出了味道来。。。 ( •̀ ω •́ )y

​ 这是一个很简单的问题,但是从头到尾都完完全全的被我给忽略了

如果 type 是 “r” 则文件指针连接到 command 的标准输出;如果 type 是 “w” 则文件指针连接到 command 的标准输入

问题就在这啊,命令执行有问题的,那是标准出错啊,哪里是什么标准输出啊,忽略了这个问题,绕了一个大圈子,最后又回来了 /(ㄒoㄒ)/~~

  • 所以,使用的函数一定要清楚其用法和定义,一定不要出错
  • 最后,不要忘记。除了标准输入、输出,它还有一个标准出错

在Linux下,不管你是启动一个桌面程序也好,还是在控制台下运行命令。所有的程序在结束时.都会返回一个数字值、这个值叫做返回值或者称为错误号(Error Number )。

​ 在控制台下,有一个特殊的环境变量"$?",保存着前一个程序的返回值,上面已经用过了。

  • 上一篇: 开窗函数 rows between
  • 下一篇: zip解压-压缩
  • 版权声明


    相关文章:

  • 开窗函数 rows between2024-12-06 16:01:00
  • 灰度发布的目标2024-12-06 16:01:00
  • ce认证公告机构查询2024-12-06 16:01:00
  • jdk环境变量如何配置?有没有遇到坑?2024-12-06 16:01:00
  • js数组操作方法2024-12-06 16:01:00
  • zip解压-压缩2024-12-06 16:01:00
  • jdbc使用流程2024-12-06 16:01:00
  • 权限administrator2024-12-06 16:01:00
  • java nio网络编程2024-12-06 16:01:00
  • 指针数组与数组指针详解2024-12-06 16:01:00