Python中os.system()的返回值是什么?

86

我遇到了这个问题:

>>> import os
>>> os.system('ls')
file.txt README
0

os.system() 的返回值是什么?为什么我得到的是 0?


os.system("ls") 用于运行一个命令,只关心它是否运行。如果你想要 stdout 输出,可以使用类似 commands.getstatusoutput("ls")[1] 的东西,如此定义:https://docs.python.org/2/library/commands.html - Eric Leschinski
1
但是 os.system("ls") 会输出 ls 的结果,除非你采取其他措施。我不确定在这种情况下是否想要抑制额外的输出,但如果你确实想要这样做,一种方法是 os.system("ls > /dev/null 2>&1") - Christos Hayward
1
显而易见的是,os.system 的文档明确建议您避免使用它,而改用 subprocess。有一个函数可以运行命令并返回其结果代码(subprocess.call),还有一个函数可以检索命令的输出(subprocess.check_output),以及一个在命令失败时会失败的函数(subprocess.check_call)。还有一个现代化的高级函数 subprocess.run 可以执行所有这些操作,甚至更多。 - tripleee
6个回答

84
os.system 的返回值取决于操作系统。

在 Unix 上,返回值是一个包含两个不同信息的 16 位数字。从文档中可以看到:

一个 16 位数字,其低字节是杀死进程的信号编号,高字节是退出状态(如果信号编号为零)

因此,如果信号编号(低字节)为0,则理论上安全的方式是将结果右移8位 (result >> 8) 以获取错误代码。函数os.WEXITSTATUS 正好做到了这一点。如果错误代码为0,则通常表示进程已经正常退出,没有错误发生。

在 Windows 上,文档指定 os.system 的返回值取决于 shell 程序。如果使用的是 cmd.exe (默认的),则该值是进程的返回码。同样,0 表示没有发生错误。

有关其他错误代码的详细信息:


操作系统维护一个errno变量,它保存了最近执行进程的退出状态。errno是全局的,执行后将返回该errno值,以指示命令是成功执行还是失败。 - deepak
2
@SteveBennett 谢谢,我修复了链接。你为什么认为它不符合答案的要求?问题是“这个数字是什么”,我给出了答案。 - rubik
1
@SteveBennett 最重要的是0(在各个系统中都有相同的含义),而其他所有代码都取决于系统。因此需要提供链接。 如果我必须添加一个摘要,我将不得不添加一个表格,其中包含两个页面的一些(任意的?)代码。这可能是不必要的,因为大多数读者只关心一个平台的返回代码。 - rubik
1
@brandones 感谢您指出这一点。这个答案是很久以前写的,显然缺少了重要的信息。现在应该是正确的了。 - rubik
7
很好。抱歉语气有些不好,我刚刚花了一段时间来解决这样的错误。请注意,您可以使用os.WEXITSTATUS(os.system(command))来获取退出状态。 - brandones
显示剩余6条评论

36

os.system('command') 返回一个16位数字,其中从右边(最低有效位)开始的前8位表示操作系统用于关闭命令的信号,接下来的8位表示命令的返回代码。

00000000    00000000
exit code   signal num

示例1 - 命令以代码1退出

os.system('command') #it returns 256
256 in 16 bits -  00000001 00000000
Exit code is 00000001 which means 1

示例2 - 命令以代码3退出
os.system('command') # it returns 768
768 in 16 bits  - 00000011 00000000
Exit code is 00000011 which means 3

现在尝试使用信号 - 示例3 - 编写一个程序,在os.system()中使用它作为命令,让其长时间休眠,然后通过kill -15或kill -9来终止它。
os.system('command') #it returns signal num by which it is killed
15 in bits - 00000000 00001111
Signal num is 00001111 which means 15

你可以将一个Python程序作为命令 = 'python command.py'。
import sys
sys.exit(n)  # here n would be exit code

在C或C++程序中,你可以在main()函数中使用return语句,或者在任何函数中使用exit(n)语句来退出程序。请注意,这仅适用于Unix系统。

On Unix, the return value is the exit status of the process encoded in the format specified for wait(). Note that POSIX does not specify the meaning of the return value of the C system() function, so the return value of the Python function is system-dependent.

os.wait()

Wait for completion of a child process, and return a tuple containing its pid and exit status indication: a 16-bit number, whose low byte is the signal number that killed the process, and whose high byte is the exit status (if the signal number is zero); the high bit of the low byte is set if a core file was produced.

Availability: Unix

.


你能否发布任何文件或链接来证明这一点? - shane
1
@shane 我的答案适用于Unix,我不确定Windows是否适用。我参考了以下链接- https://docs.python.org/2/library/os.html#os.system,它说返回值将根据系统调用wait()而定,然后我参考了-https://docs.python.org/2/library/os.html#os.wait - AlokThakur
5
请注意,您可以使用 os.WEXITSTATUS(os.system(my_call)) 获取返回代码。例如,sys.exit(os.WEXITSTATUS(os.system('exit 2'))) 将以状态码2退出。 - brandones

20

你可能希望使用

return_value = os.popen('ls').read()

相反,os.system 只返回错误值。

os.popen 是一个更整洁的包装器,用于 subprocess.Popen 函数,正如在 Python 源代码中所看到的那样。


1
另一种对os.system文档中明确指导的疯狂替代方案是改用subprocess - tripleee
@triplee 我认为如果你查看实际的Python代码中的os.popen函数(https://github.com/python/cpython/blob/master/Lib/os.py),你会发现它无论如何都使用subprocess.Popen。 - user2589273

14
“在Unix中,返回值是进程退出状态,按照wait()指定的格式进行编码。需要注意的是,POSIX没有指定C系统()函数返回值的含义,因此Python函数的返回值取决于系统实现。”

http://docs.python.org/library/os.html#os.system

“没有错误发生,因此退出代码为零。”

1
而os.wait()的返回代码编码了返回值和杀死进程的信号。请参见https://dev59.com/zVvUa4cB1Zd3GeqPxM4N#7616227。 - pwan

6

os.system() 返回的是一些 Unix 输出,而不是命令输出。因此,如果没有错误,则退出代码写为 0。


0

这段代码检查系统中是否存在该命令。它使用一个名为command的shell内置程序来实现这个目的。还有一个名为hash的内置程序,但在检查执行速度后,我确定command更快:

if os.system("command -v command_name_here") == 0: ...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接