子进程返回的代码与“echo$?”不同

2024-10-01 00:32:32 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用子进程在Python中调用bash命令,得到的返回代码与shell显示的不同。在

import subprocess
def check_code(cmd):
    print "received command '%s'" % (cmd)
    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    p.wait()
    print "p.returncode is '%d'" % (p.returncode)
    exit()
    if p.returncode == 0:
        return True
    else:
        return False
    #End if there was a return code at all
#End get_code()

当发送“ls/dev/dsk>;/dev/null”时,check_代码返回0,但“echo$?”在终端生成“2”:

^{pr2}$

有人知道这是怎么回事吗?在


Tags: 代码devcmdtruereturnif进程check
3条回答

根据^{},Python脚本中使用的shell是sh。这个shell是POSIX标准,与Bash不同,Bash有几个非标准特性,比如速记重定向&> /dev/nullsh,bourneshell,将这个符号解释为“在后台运行我,并将stdout重定向到/dev/null”。在

由于您的subprocess.Popen打开了一个在其自身背景下运行ls的{},因此使用sh的返回值,而不是{},在本例中为0。在

如果您希望Python具有Bash行为,我相信您可能需要重新配置(可能重新编译)Python本身。只使用sh语法更简单,即ls /dev/dsk 2> /dev/null。在

根据XIY的建议,我将命令分割到空间划定的字段中,并且没有用“&&GT”和“/DEV/NULL”运行。我把它们移走了,效果很好。在

然后,我将所有命令放回原处,在没有“&;>;/dev/null”的情况下对其进行了测试,这也起到了作用。添加“&;>;/dev/null”似乎会以某种方式关闭子进程。在

Welcome to Dana version 0.7
Now there is Dana AND ZOL

received command 'cat /etc/fstab'
p.wait() is 0
p.returncode is '0'

received command 'cat /etc/fstabb'
p.wait() is 1
p.returncode is '1'

received command 'cat /etc/fstab &> /dev/null'
p.wait() is 0
p.returncode is '0'

received command 'cat /etc/fstabb &> /dev/null'
p.wait() is 0
p.returncode is '0'
root@Ubuntu-14:~# cat /etc/fstab &> /dev/null
root@Ubuntu-14:~# echo $?
0
root@Ubuntu-14:~# cat /etc/fstabb &> /dev/null
root@Ubuntu-14:~# echo $?
1
root@Ubuntu-14:~#

我最初在调用中添加了“&;>;/dev/null”,因为我在屏幕上看到了STDERR的输出。一旦我将stderr=PIPE添加到子进程调用中,这种情况就消失了。我只是想悄悄地检查后台输出的代码。在

如果有人能解释为什么在Python中向子进程调用添加“&;>;/dev/null”会导致它出现意外行为,我很乐意选择这个作为答案!在

您将它用作subprocess.Popen(cmd, shell=True),而cmd作为字符串。在

这意味着子进程将使用参数在底层调用/bin/sh。所以你得到了你的shell的退出代码。在

如果您确实需要命令的退出代码,请将其拆分为list并使用shell=False。在

subprocess.Popen(['cmd', 'arg1'], shell=False)

相关问题 更多 >