整数文件描述符"0"在open()中 [英] Integer File Descriptor "0" in open()
问题描述
在Python 3中,可以使用整数" 打开文件对象文件描述符" ,其格式为:
stdout = open(1,"w")stdout.write("Hello World")#打印Hello Worldstdout.close()
尽管,有趣的是,我发现 0
也是有效的流.
如果我将其放在文件 testio.py
中:
stdout = open(0,"w")stdout.write("Foo Bar \ n")stdout.close()
然后运行该代码,输出为:
bash-3.2 $ python3 testio.pyFoo酒吧
似乎就像 stdout
一样.但是...
bash-3.2 $ python3 testio.py>testio.txtFoo酒吧bash-3.2 $ cat testio.txt
所以看来这实际上不是 stdout
,而是其他东西.而且它似乎也不是 stderr
:
bash-3.2 $ python3 testio.py 2>testio.txtFoo酒吧bash-3.2 $ cat testio.txt
但是,我确实发现可以使用 0>
重定向输出:
bash-3.2 $ python3 testio.py 0>testio.txtbash-3.2 $ cat testio.txtFoo酒吧
所以我的问题是, open(0,"w")
应该是什么?重定向的"0>"流是什么?
Python 3.6.5
重击3.2
没有文件描述符(FD)编号是特殊的.FD 0上的stdin,FD 1上的stdout和FD 2上的stderr只是一个约定.
登录时,关联的终端设备将连接"到这些FD.运行命令时,除非您指示Shell进行重定向,否则它会继承描述符.但是一旦程序启动,您就可以根据需要随意 close
, dup
或 open
FD.
回到您的问题:
stdout = open(0,"w")stdout.write("Hello World")#打印Hello Worldstdout.close()
尽管名称,但 open
在这种情况下不会打开任何内容.它从已经打开的低级FD创建一个Python文件对象(带有缓冲区和所有高级内容),它实际上只是一个数字(内核中打开文件表的索引).它有一个单独的功能: os.fdopen >
更有趣的一点是,没有标准的方法可以将打开模式从读取更改为写入,而您的程序将写入标准输入.答案是(至少在Linux上)这根本没有发生.从 lsof
可以看到,所有3个标准FD通常以读/写模式打开(以 u
结尾),例如:
cmd 32154用户0u CHR 136,7 0t0 10/dev/pts/7cmd 32154用户1u CHR 136,7 0t0 10/dev/pts/7cmd 32154用户2u CHR 136,7 0t0 10/dev/pts/7
因此,您的程序只需写入连接到终端的FD 0.
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()
Though, interestingly, I found that 0
is also a valid stream.
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
Which seems just like stdout
. However...
bash-3.2$ python3 testio.py > testio.txt
Foo Bar
bash-3.2$ cat testio.txt
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
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
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
Bash 3.2
No file descriptor (FD) number is special. stdin on FD 0, stdout on FD 1 and stderr on FD 2 is just a convention.
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.
Back to your question:
stdout = open(0, "w")
stdout.write("Hello World") # Prints Hello World
stdout.close()
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
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
So your program just writes to the FD 0 which is connected to the terminal.
这篇关于整数文件描述符"0"在open()中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!