subprocess.wait()的返回码有几种?
我对一个用来从服务器复制文件到Hadoop的Python文件感到很困惑。
命令是:hadoop fs -put /localhost/* /hadoop/*
,代码如下:
cmd = exc_path + ' ' + 'fs -put' + ' ' + src_path + item + ' ' + dst_path
process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
code = process.wait()
logfile.info('type(code) is %s, code is %s\n', type(code), code)
过去几天,这个程序运行得很好。但是前天它返回了code!=0
。昨天又正常运行,返回了code == 0
,而今天又失败了,返回了:type(code) is <type 'int'>, code is 255
文档上说wait()
应该返回0或者None,那我为什么会得到255呢?而Hadoop的put
命令应该在成功时返回0,在失败时返回-1。
我找到了一些有用的信息:“可悲的是,当你使用shell=True运行子进程时,wait()只会等待sh子进程完成,而不会等待命令cmd。” 来源
2 个回答
返回代码255意味着Hadoop进程以-1
的返回代码结束(为什么会这样我也不知道)。
之所以wait()
不会给你-1,是因为负数的返回值是用来表示子进程是因为信号而结束的情况(比如,如果子进程是因为信号11结束的,返回代码就会是-11)。
文档说 wait() 应该返回 0 或 None,但我为什么得到 255 呢?
这是不对的。文档中说:
Popen.wait() 等待子进程结束。设置并返回 returncode 属性。
还有:
Popen.returncode 子进程的返回代码,由 poll() 和 wait() 设置(间接由 communicate() 设置)。 None 值表示进程还没有结束。 负值 -N 表示子进程是被信号 N 终止的(仅限 Unix)。
如果命令以非零的退出代码结束,那么你就会得到这个代码。
而 hadoop 的 'put' 命令应该在成功时返回 0,在失败时返回 -1。
你得到 255
而不是 -1
的原因其实很简单,已经在 这里 和 这里 解释过了。基本上,这是因为 Java 允许使用带符号的 32 位值作为退出代码(对我们来说是 -1),而 Posix 的退出状态是无符号的 8 位值。
总结一下,非零的退出代码会告诉你命令失败了。如果你想检查特定的退出代码,当这个代码不在 0-255 范围内时,必须特别小心。