问题描述
在Python 3中,可以使用整数" 打开文件对象文件描述符" ,其格式为:
In Python 3, it is possible to open a file object using an "integer file descriptor" with the format:
stdout = open(1, "w")
stdout.write("Hello World") # Prints Hello World
stdout.close()
但是,有趣的是,我发现0
也是有效的流.
Though, interestingly, I found that 0
is also a valid stream.
如果我将其放在文件testio.py
中:
If I put this in the file testio.py
:
stdout = open(0, "w")
stdout.write("Foo Bar\n")
stdout.close()
然后运行该代码,输出为:
And then run that code the output is:
bash-3.2$ python3 testio.py
Foo Bar
似乎与stdout
类似.但是...
Which seems just like stdout
. However...
bash-3.2$ python3 testio.py > testio.txt
Foo Bar
bash-3.2$ cat testio.txt
所以看来这实际上不是stdout
,而是其他.而且它似乎也不是stderr
:
So it seems that this is actually not stdout
, but something else.And it does not appear to be stderr
either:
bash-3.2$ python3 testio.py 2> testio.txt
Foo Bar
bash-3.2$ cat testio.txt
但是,我确实发现可以使用0>
重定向输出:
However, I did find that the output can be redirected using 0>
:
bash-3.2$ python3 testio.py 0> testio.txt
bash-3.2$ cat testio.txt
Foo Bar
所以我的问题是,open(0, "w")
到底应该是什么?重定向的"0>"流是什么?
So my question is, what exactly does open(0, "w")
due? And what is this "0>" stream that is being redirected?
Python 3.6.5
重击3.2
Python 3.6.5
Bash 3.2
推荐答案
没有文件描述符(FD)编号是特殊的. FD 0上的stdin,FD 1上的stdout和FD 2上的stderr只是一个约定.
No file descriptor (FD) number is special. stdin on FD 0, stdout on FD 1 and stderr on FD 2 is just a convention.
登录时,关联的终端设备将连接"到这些FD.运行命令时,除非您指示Shell进行重定向,否则它会继承描述符.但是一旦程序启动,您就可以根据需要选择close
,dup
或open
FD.
When you log in, the associated terminal device will be "connected" to these FDs. When you run a command, it inherits the descriptors unless you instruct the shell to make redirections. But once the program starts, you can close
, dup
, or open
FDs as you like.
回到您的问题:
stdout = open(0, "w")
stdout.write("Hello World") # Prints Hello World
stdout.close()
尽管名称,但open
在这种情况下不会打开任何内容.它从已经打开的低级FD创建一个Python文件对象(带有缓冲区和所有高级内容),它实际上只是一个数字(内核中打开文件表的索引).它有一个单独的函数: os.fdopen
Despite the name, open
does not open anything in this case. It creates a Python file object (with buffers and all high level stuff) from an already open low-level FD which is really just a number (an index to a table of open files in the kernel). There was a separate function for it: os.fdopen
更有趣的一点是,没有标准的方法可以将打开模式从读取更改为写入,而您的程序将写入标准输入.答案是(至少在Linux上)这根本没有发生.从lsof
可以看到,所有3个标准FD通常在读/写模式下打开(以u
结尾),例如:
Little bit more interesting is that there is no standard way to change the open mode from read to write and your program writes to std input. The answer is (at least on Linux) that this is not happening at all. As you can see with lsof
, all 3 standard FDs are normally open in read/write mode (marked by trailing u
), e.g.:
cmd 32154 user 0u CHR 136,7 0t0 10 /dev/pts/7
cmd 32154 user 1u CHR 136,7 0t0 10 /dev/pts/7
cmd 32154 user 2u CHR 136,7 0t0 10 /dev/pts/7
因此,您的程序只需写入连接到终端的FD 0.
So your program just writes to the FD 0 which is connected to the terminal.
这篇关于整数文件描述符"0"在open()中-Python 3的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!