/tmp$ python
Python 2.7.6 (default, Nov 13 2018, 12:45:42)
[GCC 4.8.4] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> f1 = open("/tmp/doo1","w")
>>> f2 = open("/tmp/doo2","w")
>>> f3 = open("/tmp/doo3","w")
>>> f4 = open("/tmp/doo4","w")
>>> f5 = open("/tmp/doo5","w")
>>> f6 = open("/tmp/doo6","w")
>>> f7 = open("/tmp/doo7","w")
>>> f8 = open("/tmp/doo8","w")
>>> f9 = open("/tmp/doo9","w")
>>> f5.fileno()
7
>>> os.system("cat /file_to_copy >&7") # works fine
0
>>> f7.fileno()
9
>>> os.system("cat /file_to_copy >&9") # works fine
0
>>> f8.fileno()
10
>>> os.system("cat /file_to_copy >&10") # does not work
sh: 1: Syntax error: Bad fd number
512
>>> f9.fileno()
11
>>> os.system("cat /file_to_copy >&11") # does not work
sh: 1: Syntax error: Bad fd number
512
为什么 I/O 重定向仅支持 fd <= 9?做了 strace 并无法找出问题所在。尽管我粘贴了 Python 代码,但由于系统调用 shell,C++ 代码也会出现同样的问题。
我的用例是 ssh 到远程计算机并猫远程文件到本地文件。本地文件是先前创建的并立即取消链接,以便其他用户/进程无法看到它。因此将 cat 输出重定向到本地文件 fd 而不是本地文件路径。
fd = open("/tmp/doo",O_CREAT|O_RDWR);
unlink("/tmp/doo");
...
...
system will run this - "ssh -n user@remotehost -- cat /remote_file >&fd"
编辑 - 看起来 fd 10 及以上被保留。从:https://github.com/MirBSD/mksh/blob/master/sh.h
/* first fd number usable by the shell for its own purposes */
#define FDBASE 10
/* … and last one */
#define FDMAXNUM 127 /* 0x7FU, cf. FDNUMMASK */