gpt4 book ai didi

linux - Bash 文件描述符与 Linux 文件描述符

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:02:53 29 4
gpt4 key购买 nike

我只是想调和这两个看似相似的概念。

在 Bash 中,允许进行任意重定向,重要的是,可以使用自己选择的文件描述符编号。但是在 Linux 中,调用进程无法选择 open 调用 (AFAIK) 返回的值。

那么,Bash fd numbers 和系统调用返回的 fd numbers 一样吗?如果不是,有什么区别?

最佳答案

这里有一个小实验,可以让您了解当您在 bash 中打开一个文件描述符时发生的情况,其中包含您选择的一些数字:

> cat test.txt
foobar!

> cat test.sh
#!/bin/bash
exec 17<test.txt
read -u 17 line
echo "$line"
exec 17>&-

> strace ./test.sh
//// A bunch of stuff omitted so we can skip to the interesting part...
open("test.txt", O_RDONLY) = 3
fcntl(17, F_GETFD) = -1 EBADF (Bad file descriptor)
dup2(3, 17) = 17
close(3) = 0
fcntl(17, F_GETFD) = 0
ioctl(17, TCGETS, 0x7ffc56f093f0) = -1 ENOTTY (Inappropriate ioctl for device)
lseek(17, 0, SEEK_CUR) = 0
read(17, "foobar!\n", 128) = 8
write(1, "foobar!\n", 8foobar!) = 8
fcntl(17, F_GETFD) = 0
fcntl(17, F_DUPFD, 10) = 10
fcntl(17, F_GETFD) = 0
fcntl(10, F_SETFD, FD_CLOEXEC) = 0
close(17) = 0

回答您问题的部分是它在 test.txt 上调用 open() 的地方,它返回值 3。这是您最有可能得到的结果在 C 程序中,如果您也这样做,因为文件描述符 0、1 和 2(即 stdinstdoutstderr)是你最初打开的所有内容。数字 3 只是下一个可用的文件描述符。

我们也在 bash 脚本的 strace 输出中看到了这一点。 bash 的不同之处在于它随后调用 fcntl(17, F_GETFD) 来检查文件描述符 17 是否已经打开(因为它想将该 fd 用于 test.txt ).然后,当 fcntl 返回 EBADF 表示没有打开这样的 fd 时,bash 知道可以免费使用它。然后它调用 dup2(3, 17) 使 fd 17 成为 fd 3 的副本。最后,它调用 fd 3 上的 close() 再次释放它,将 fd 17( fd 17)保留为 test.txt 的打开文件描述符。

所以您的问题的答案是 bash 文件描述符不是与其他人使用的“正常”文件描述符不同的特殊生物。它们实际上是同一件事。您可以轻松地在 C 程序中使用相同的技巧来打开具有您选择的文件描述符编号的文件。

此外,值得指出的是,bash 在调用 open() 时并没有真正选择自己的文件描述符。它必须像其他人一样处理 open() 返回的任何内容。在您的 bash 脚本中真正发生的一切都是一些虚幻的东西(通过 dup2()),让您看起来好像可以选择自己的文件描述符。

关于linux - Bash 文件描述符与 Linux 文件描述符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55739026/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com