我正在编写一个后台应用程序,其中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.
出了什么问题,为什么打开的文件提示为已关闭?
答案 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
会默默地关闭它复制过来的打开的文件描述符,而不关闭文件对象。)