多年来,我一直试图理解这个概念,但此时对此的了解还不完整。
这里有没有人可以通过示例来制作一种教程或很好的解释
- 开一个新的
fd
- 读自
fd
- 使用
fd
- 关闭
fd
我已经阅读了https://www.gnu.org/software/bash/manual/html_node/Redirections.html和man bash
,但不清楚,根本没有具体且易于理解的示例。
如果有人能很好地解释它,那将是一个有价值的答案,不仅对我而言。大多数时候语法有点混乱。
有时需要exec
,有时不需要。
Bourne-like shell 的一些翻译:
open("file", O_RDONLY)
exec 3< file
open("file", O_RDONLY)
exec {fd}< file
$fd
fd 在²中返回open("file", O_WRONLY|O_TRUNC|O_CREAT)
exec 3> file
open("file", O_WRONLY|O_APPEND|O_CREAT)
exec 3>> file
open("file", O_RDWR|O_CREAT)
exec 3<> file
open("file", ...)
sysopen ...
dup2(4, 5)
exec 5>&4
exec 5<&4
dup(4)
exec {fd}>&4
$fd
write(4, data, length)
print -rnu4 -- "$data"
print
bash也有一个 example loadable builtin 5write(...)
syswrite ...
read(4, var...)
sysread -i 4 ... var
zsh/system
在模块中read(4, var...)
IFS= read -ru4 ... var
close(4)
exec 4>&-
exec 4<&-
lseek(4, 123, SEEK_SET)
exec 4>#((123))
lseek(4, 123, SEEK_CUR)
exec 4>#((CUR + 123))
lseek(4, 123, SEEK_END)
exec 4>#((EOF + 123))
lseek(...)
sysseek ...
pipe()
exec 4>>|5
fstat(4, var)
zstat -f 4 -H var
select(...)
zselect ...
zsh 也有一些
zsh/net/socket
,zsh/net/tcp
,zsh/zpty
模块来创建一个操作其他种类的 fds。使用
exec
更改 shell 进程的文件描述符。然而,大多数时候,您只想更改其他一些命令的文件描述符,例如ls -l dir/ > file
(简称)以仅在 fd 1(stdout)上ls -l dir/ 1> file
打开,或一段代码:file
ls
foo | bar
在并发进程中执行pipe()
7后跟一些dup2()
s 或等价物和close()
s 因此将运行的进程的 fd 1foo
进入管道的写入端,fd 0 或bar
进入读取端。其他使用或可能使用管道的 shell 构造包括命令替换 (var=$(cmd)
,var=`cmd`
)、类 Korn shell 进程替换 (foo <(bar) >(baz)
)、协同进程、yash 的进程重定向。¹ 在 ksh93 和 bash 中,如果
file
是/dev/tcp|udp/host/port
,它不会真正打开,而是创建一个网络套接字。² 其他
>
,>>
,<>
,>
运营商也可以这样做³ 如果
noclobber
打开该选项,O_EXCL
则在目标是常规文件时添加 a,根据 shell可以使用>|
或运算符绕过该文件>!
4在Bourne shell中,没有
O_APPEND
,但是打开后shell会寻尾5在其他 shell 中,您始终可以这样做
printf %s "$var" >&4
。这不会写入 fd 4,而是写入 fd 1,经过一个临时的,dup2(4, 1)
实际上实现了相同的目标。同样的IFS= read -r line <&4
。6另见
systell(fd)
返回 fd 位置的数学函数,这是另一个接口lseek()
7某些使用
socketpair()
s 而不是管道的系统上的 ksh93 除外。其他一些使用管道的结构也是如此。首先,您不应将自己局限于 shell 脚本。文件描述符的概念来自操作系统和 C。Shell 脚本教科书提到文件描述符,但它们实际上隐藏在 shell 解释器本身内部。所以像“如何在 shell 中打开一个新的 fd”这样的问题实际上没有意义,因为你不直接在 shell 中使用文件描述符。
要直接使用文件描述符,你必须使用 C。所有其他语言都是建立在用 C 编写的库和虚拟机之上的。所以,如果你对这个主题感兴趣,你必须学习 C。请不要将它与C++——这个也可以用于与操作系统的直接通信,但它有太多的“帮助内容”,这将成为理解操作系统任务的障碍。
当然,您需要阅读有关操作系统组织方式的教科书。最好的书:Andrew Tanenbaum 着的《Modern Operating Systems》。它在任何书店和图书馆都可以买到。