Я пишу фоновое приложение, в котором 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.
Что происходит, почему открытый файл отображается как закрытый?
Вы уже закрыли стандартный вывод:
sys.stdout.close()
поэтому в следующий раз, когда вы попытаетесь использовать print
что-нибудь (по умолчанию на стандартный вывод), вы получите исключение ValueError: I/O operation on closed file.
. Так что нет, это не имеет ничего общего с доступом к методу fileno()
si
.
Файловые объекты Python не являются дескрипторами файлов. Когда вы закрываете файловый объект, он остается закрытым независимо от того, повторно используется ли файловый дескриптор, в который он помещен.
Ваши вызовы dup2
повторно используют файловые дескрипторы, изначально назначенные для stdin и stdout, но чтобы заставить файловые объекты работать, вам нужно либо не вызывать close
для исходных файловых объектов stdin / stdout, либо заменять их новыми файловыми объектами. (Пропуск вызовов close
- это нормально, потому что dup2
молча закроет открытые файловые дескрипторы, которые он копирует, без закрытия файловых объектов.)