Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/349.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 什么';关闭的文件描述符是怎么回事?_Python_Unix_File Descriptor_Python Os - Fatal编程技术网

Python 什么';关闭的文件描述符是怎么回事?

Python 什么';关闭的文件描述符是怎么回事?,python,unix,file-descriptor,python-os,Python,Unix,File Descriptor,Python Os,在下面的示例代码中,我们将文件描述符打开到sandbox.log,将其作为stdout提供给子流程,然后关闭文件描述符,但子流程仍然可以写入该文件。subprocess.Popen是否在内部复制文件描述符?将文件描述符传递给子进程后关闭它是否安全 import subprocess import os import time print 'create or clear sandbox.log' subprocess.call('touch sandbox.log', shell=True)

在下面的示例代码中,我们将文件描述符打开到sandbox.log,将其作为stdout提供给子流程,然后关闭文件描述符,但子流程仍然可以写入该文件。subprocess.Popen是否在内部复制文件描述符?将文件描述符传递给子进程后关闭它是否安全

import subprocess
import os
import time


print 'create or clear sandbox.log'
subprocess.call('touch sandbox.log', shell=True)
subprocess.call('echo "" > sandbox.log', shell=True)

print 'open the file descriptor'
fd = os.open('sandbox.log', os.O_WRONLY)

command = 'sleep 10 && echo "hello world"'
print 'run the command'
p = subprocess.Popen(command, stdout=fd, stderr=subprocess.STDOUT, shell=True)

os.close(fd)

try:
    os.close(fd)
except OSError:
    print 'fd is already closed'
else:
    print 'fd takes some time to close'

if p.poll() is None:
    print 'p isnt finished, but fd is closed'

p.wait()
print 'p just finished'

with open('sandbox.log') as f:
    if any('hello world' in line for line in f):
        raise Exception("There's text in sandbox.log. Whats going on?")
作为参考,我得到了以下输出,以脚本的形式运行上述代码:

% python test_close_fd.py
create or clear sandbox.log
open the file descriptor
run the command
fd is already closed
p isnt finished, but fd is closed
p just finished
Traceback (most recent call last):
  File "test_close_fd.py", line 34, in <module>
    raise Exception("There's text in sandbox.log. Whats going on?")
Exception: There's text in sandbox.log. Whats going on?
%python测试\u关闭\u fd.py
创建或清除sandbox.log
打开文件描述符
运行命令
fd已关闭
p未完成,但fd已关闭
p刚刚结束
回溯(最近一次呼叫最后一次):
文件“test_close_fd.py”,第34行,在
引发异常(“sandbox.log中有文本。发生了什么事?”)
例外:sandbox.log中有文本。发生什么事了?

每个进程都有自己的文件描述符集。关闭一个程序中的fd不会影响另一个程序。这就是为什么每个程序都可以对stdin(0)、stdout(1)和stderr(2)使用相同的fd编号,以及为什么shell脚本通常可以只打开fd3而不必检查它是否可用


文件描述符由子进程继承,除非通过设置close on exec标志显式阻止它。默认情况下,如果没有该标志,子进程将获得父进程的文件描述符的副本。

谢谢John。你的回答很有启发性。从外观上看,你正在使用Python 2。请参见
close_fds
参数至
Popen
。由于这些原因,默认值在3.2中更改。