微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

open()中的整数文件描述符“0” – Python 3

Python 3中,可以使用以下格式的open a file object using an “integer file descriptor”

stdout = open(1, "w")
stdout.write("Hello World") # Prints Hello World
stdout.close()

虽然,有趣的是,我发现0也是一个有效的流.

如果我把它放在文件testio.py中:

stdout = open(0, "w")
stdout.write("Foo Bar\n")
stdout.close()

然后运行该代码输出是:

bash-3.2$python3 testio.py
Foo Bar

这看起来就像stdout.然而…

bash-3.2$python3 testio.py > testio.txt
Foo Bar
bash-3.2$cat testio.txt

所以看起来这实际上不是stdout,而是其他东西.
它似乎也不是stderr:

bash-3.2$python3 testio.py 2> testio.txt
Foo Bar
bash-3.2$cat testio.txt

但是,我确实发现可以使用0>重定向输出

bash-3.2$python3 testio.py 0> testio.txt
bash-3.2$cat testio.txt
Foo Bar

所以我的问题是,open(0,“w”)究竟应该是什么?什么是“0>”正在重定向的流?

Python 3.6.5
Bash 3.2

解决方法:

没有文件描述符(FD)号是特殊的. FD 0上的stdin,FD 1上的stdout和FD 2上的stderr只是一个约定.

登录时,关联的终端设备将“连接”到这些FD.当您运行命令时,它会继承描述符,除非您指示shell进行重定向.但是一旦程序启动,您可以根据需要关闭,复制或打开FD.

回到你的问题:

stdout = open(0, "w")
stdout.write("Hello World") # Prints Hello World
stdout.close()

尽管有这个名字,open在这种情况下不会打开任何东西.它从已经打开的低级FD创建一个Python文件对象(带缓冲区和所有高级东西),它实际上只是一个数字(内核中打开文件表的索引).它有一个单独的功能os.fdopen

更有趣的是,没有标准的方法可以将打开模式从读取更改为写入,并且程序会写入标准输入.答案是(至少在Linux上),这根本不会发生.正如你可以看到的lsof,所有3个标准FD通常都是以读/写模式打开(以尾随u标记),例如:

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.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐