python3:fileno()在关闭的文件错误上引发I / O操作

时间:2018-10-26 06:20:54

标签: python python-3.x

我正在编写一个后台应用程序,其中stdin,stdout和stderr将从文件重定向到文件。我的代码如下:

#! /usr/bin/python3

import sys
import os

# Custom I/O files
myStdin = './stdin'
myStdout = './stdout'
myStderr = './stderr'

# Create empty files to be used by child to redirect I/O
open(myStdin, 'a').close()
open(myStdout, 'a').close()
open(myStderr, 'a').close()

# Close standard file descriptors before spawnning child
sys.stdout.flush()
sys.stderr.flush()
sys.stdin.close()
sys.stdout.close()
#sys.stderr.close()

# spawn child and parent exits gracefully
p = os.fork()
if p:
    sys.exit(0)

# open files to redirect I/O (Non-buffered)
si = open(myStdin, 'r')
so = open(myStdout, 'ab+', 0)
se = open(myStderr, 'ab+', 0)

print(si.fileno())

# Duplicate the file descriptors
os.dup2(si.fileno(), 0)
os.dup2(so.fileno(), 1)
#os.dup2(se.fileno(), 2)

# Update the standard file objects with custom once
sys.stdin = si
sys.stdout = so
#sys.stderr = se

但是,出现以下错误:

 Traceback (most recent call last):
  File "./test.py", line 33, in <module>
    print(si.fileno())
ValueError: I/O operation on closed file.

出了什么问题,为什么打开的文件提示为已关闭?

2 个答案:

答案 0 :(得分:2)

您已经使用以下命令关闭了标准输出:

sys.stdout.close()

因此,下次您尝试print 任何内容(默认情况下为标准输出)时,您将获得ValueError: I/O operation on closed file.异常。因此,不,它与访问fileno()的{​​{1}}方法没有任何关系。

答案 1 :(得分:1)

Python文件对象不是文件描述符。关闭文件对象时,无论包装的文件描述符是否被重用,它都会保持关闭状态。

您的dup2调用重用了最初分配给stdin和stdout的文件描述符,但是要使文件对象正常工作,您需要不对原始stdin / stdout文件对象调用close或替换他们与新的文件对象。 (跳过close调用是可以的,因为dup2会默默地关闭它复制过来的打开的文件描述符,而不关闭文件对象。)