额外减小 发表于 2023-2-21 21:08:45

关于os.popen(...).read()的问题

如题

我在cmd里面写相应的命令,他可以正常显示
(发现一个,好像gcc前缀的都不能正常显示)
C:\Users\summer\Desktop\codehome>gcc kfkff.c
gcc: error: kfkff.c: No such file or directory
gcc: fatal error: no input files
compilation terminated.
我在代码里面这么写,他只给我返回了空的字符串
>>> os.popen('gcc kfkff.c').read()
''
请问用os.popen()函数为什么不能正常读取输出的内容
(我试了下,其他命令都可以)
>>> os.popen('ipconfig').read()
'\nWindows IP 配置\n\n\n无线局域网适配器 本地连接* 3:\n\n   媒体状态. . . . . . . . . . . . : 媒体已断开连接\n   连接特定的 DNS 后缀 . . . . . . . : \n\n无线局域网适配器 本地连接* 12:\n\n   媒体状态. . . . . . . . . . . . : 媒体已断开连接\n   连接特定的 DNS 后缀 . . . . . . . : \n\n无线局域网适配器 WLAN:\n\n   连接特定的 DNS 后缀 . . . . . . . : \n   本地链接 IPv6 地址. . . . . . . . : xxxxxxxxxxxxxxxxxxxxxx\n   IPv4 地址 . . . . . . . . . . . . : xxxxxxxxxx\n   子网掩码. . . . . . . . . . . . : xxxxxxxxxxxx\n   默认网关. . . . . . . . . . . . . : xxxxxxxxxxxxxxxxx\n'
>>> os.popen('pip -v').read()
"\nUsage:   \npip <command> \n\nCommands:\ninstall                     Install packages.\ndownload                  Download packages.\nuninstall                   Uninstall packages.\nfreeze                      Output installed packages in requirements format.\nlist                        List installed packages.\nshow                        Show information about installed packages.\ncheck                     Verify installed packages have compatible dependencies.\nconfig                      Manage local and global configuration.\nsearch                      Search PyPI for packages.\ncache                     Inspect and manage pip's wheel cache.\nindex                     Inspect information available from package indexes.\nwheel                     Build wheels from your requirements.\nhash                        Compute hashes of package archives.\ncompletion                  A helper command used for command completion.\ndebug                     Show information useful for debugging.\nhelp                        Show help for commands.\n\nGeneral Options:\n-h, --help                  Show help.\n--debug                     Let unhandled exceptions propagate outside the\n                              main subroutine, instead of logging them to\n                              stderr.\n--isolated                  Run pip in an isolated mode, ignoring\n                              environment variables and user configuration.\n--require-virtualenv      Allow pip to only run in a virtual environment;\n                              exit with an error otherwise.\n-v, --verbose               Give more output. Option is additive, and can be\n                              used up to 3 times.\n-V, --version               Show version and exit.\n-q, --quiet               Give less output. Option is additive, and can be\n                              used up to 3 times (corresponding to WARNING,\n                              ERROR, and CRITICAL logging levels).\n--log <path>                Path to a verbose appending log.\n--no-input                  Disable prompting for input.\n--proxy <proxy>             Specify a proxy in the form\n                              proxy.server:port.\n--retries <retries>         Maximum number of retries each connection should\n                              attempt (default 5 times).\n--timeout <sec>             Set the socket timeout (default 15 seconds).\n--exists-action <action>    Default action when a path already exists:\n                              (s)witch, (i)gnore, (w)ipe, (b)ackup, (a)bort.\n--trusted-host <hostname>   Mark this host or host:port pair as trusted,\n                              even though it does not have valid or any HTTPS.\n--cert <path>               Path to PEM-encoded CA certificate bundle. If\n                              provided, overrides the default. See 'SSL\n                              Certificate Verification' in pip documentation\n                              for more information.\n--client-cert <path>      Path to SSL client certificate, a single file\n                              containing the private key and the certificate\n                              in PEM format.\n--cache-dir <dir>         Store the cache data in <dir>.\n--no-cache-dir            Disable the cache.\n--disable-pip-version-check\n                              Don't periodically check PyPI to determine\n                              whether a new version of pip is available for\n                              download. Implied with --no-index.\n--no-color                  Suppress colored output.\n--no-python-version-warning\n                              Silence deprecation warnings for upcoming\n                              unsupported Pythons.\n--use-feature <feature>   Enable new functionality, that may be backward\n                              incompatible.\n--use-deprecated <feature>Enable deprecated functionality, that will be\n                              removed in the future.\n"
>>> os.popen('gcc -v').read()
''
>>>

isdkz 发表于 2023-2-21 21:15:51

本帖最后由 isdkz 于 2023-2-21 21:47 编辑

这是因为 os.popen('gcc kfkff.c').read() 是从 stdout 中读取,而报错信息是输出到 stderr,所以从 stdout 是读不到报错信息的,

你可以把 stderr 重定向到 stdout,

>>> os.popen('gcc kfkff.c 2>&1').read()
'gcc: error: kfkff.c: No such file or directory\ngcc: fatal error: no input files\ncompilation terminated.\n'
>>>

官方推荐使用 subprocess:
>>> import subproces
>>> p=subprocess.Popen("gcc kfkff.c",stderr=subprocess.PIPE)
>>> p.stderr.read()
b'gcc: error: kfkff.c: No such file or directory\ngcc: fatal error: no input files\ncompilation terminated.\r\n'
>>>

人造人 发表于 2023-2-21 21:17:50

这个read读取的是stdout吧?
那么stderr呢?

dolly_yos2 发表于 2023-2-21 21:30:16

isdkz 发表于 2023-2-21 21:15
这是因为 os.popen('gcc kfkff.c').read() 是从 stdout 中读取,而报错信息是输出到 stderr,所以从 stdout ...

也许是用目前推荐的做法会更好,比如
https://docs.python.org/3/library/subprocess.html#subprocess.Popen
https://docs.python.org/3/library/subprocess.html#replacing-os-popen-os-popen2-os-popen3

isdkz 发表于 2023-2-21 21:47:02

dolly_yos2 发表于 2023-2-21 21:30
也许是用目前推荐的做法会更好,比如
https://docs.python.org/3/library/subprocess.html#subprocess.P ...

ok,我给他加上去

ouyunfu 发表于 2023-2-21 22:25:23

os.popen()函数可以执行命令并返回一个文件对象,可以通过文件对象的方法来读取命令输出的内容。但是在您的例子中,您发现gcc -v命令的输出内容为空,这是因为gcc -v命令输出的内容是输出到标准错误流(stderr)中而不是标准输出流(stdout)中。如果要获取gcc -v命令的输出,您需要使用os.popen('gcc -v 2>&1')来将标准错误流重定向到标准输出流中。

所以您可以尝试以下代码:os.popen('gcc -v 2>&1').read()

额外减小 发表于 2023-2-21 22:29:39

isdkz 发表于 2023-2-21 21:15
这是因为 os.popen('gcc kfkff.c').read() 是从 stdout 中读取,而报错信息是输出到 stderr,所以从 stdout ...

谢谢 提醒
页: [1]
查看完整版本: 关于os.popen(...).read()的问题