子进程 return 代码不同于 "echo $?"
Subprocess return code different than "echo $?"
我正在使用子进程调用 Python 中的 bash 命令,但我得到的 return 代码与 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_code returns 0,但"echo $?"在终端中产生“2”:
Welcome to Dana version 0.7
Now there is Dana AND ZOL
received command 'ls /dev/dsk &> /dev/null'
p.returncode is '0'
root@Ubuntu-14:~# ls /dev/dsk &> /dev/null
root@Ubuntu-14:~# echo $?
2
root@Ubuntu-14:~#
有人知道这里发生了什么吗?
您将其用作 subprocess.Popen(cmd, shell=True)
,将 cmd
用作字符串。
这意味着子进程将在后台调用 /bin/sh
并带有参数。因此,您将取回 shell
.
的退出代码
如果您确实需要命令的退出代码,请将其拆分为列表并使用 shell=False
。
subprocess.Popen(['cmd', 'arg1'], shell=False)
根据 xi_ 的建议,我将命令拆分为 space 个划定的字段,但它未能 运行 使用“&>”和“/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”会导致它出现意外行为,我很乐意 select回答!
根据 subprocess.Popen
,您的 Python 脚本中使用的 shell 是 sh
。此 shell 是 POSIX 标准,与 Bash 相对,后者具有多个非标准功能,例如 shorthand 重定向 &> /dev/null
。 sh
,Bourne shell,将此符号解释为 "run me in the background, and redirect stdout to /dev/null"。
由于您的 subprocess.Popen
打开了一个 sh
,它在自己的后台运行 ls
,因此使用 sh
的 return 值而不是 ls
,在本例中为 0。
如果您希望 Python 具有 Bash 行为,我相信您可能需要重新配置(可能重新编译)Python 本身。只使用 sh
语法更简单,即 ls /dev/dsk 2> /dev/null
.
我正在使用子进程调用 Python 中的 bash 命令,但我得到的 return 代码与 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_code returns 0,但"echo $?"在终端中产生“2”:
Welcome to Dana version 0.7
Now there is Dana AND ZOL
received command 'ls /dev/dsk &> /dev/null'
p.returncode is '0'
root@Ubuntu-14:~# ls /dev/dsk &> /dev/null
root@Ubuntu-14:~# echo $?
2
root@Ubuntu-14:~#
有人知道这里发生了什么吗?
您将其用作 subprocess.Popen(cmd, shell=True)
,将 cmd
用作字符串。
这意味着子进程将在后台调用 /bin/sh
并带有参数。因此,您将取回 shell
.
如果您确实需要命令的退出代码,请将其拆分为列表并使用 shell=False
。
subprocess.Popen(['cmd', 'arg1'], shell=False)
根据 xi_ 的建议,我将命令拆分为 space 个划定的字段,但它未能 运行 使用“&>”和“/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”会导致它出现意外行为,我很乐意 select回答!
根据 subprocess.Popen
,您的 Python 脚本中使用的 shell 是 sh
。此 shell 是 POSIX 标准,与 Bash 相对,后者具有多个非标准功能,例如 shorthand 重定向 &> /dev/null
。 sh
,Bourne shell,将此符号解释为 "run me in the background, and redirect stdout to /dev/null"。
由于您的 subprocess.Popen
打开了一个 sh
,它在自己的后台运行 ls
,因此使用 sh
的 return 值而不是 ls
,在本例中为 0。
如果您希望 Python 具有 Bash 行为,我相信您可能需要重新配置(可能重新编译)Python 本身。只使用 sh
语法更简单,即 ls /dev/dsk 2> /dev/null
.