假设我有process 1和process 2。两者都有一个对应于整数 4 的文件描述符。
然而,在每个进程中,文件描述符 4 指向内核打开文件表中的一个完全不同的文件:

这怎么可能?文件描述符不应该是打开文件表中记录的索引吗?
我正在尝试使用文件描述符获取全貌。假设我有最初具有这些文件描述符的 process1:
_process1_
| |
| 0 stdin |
| 1 stdout |
| 2 stderr |
|__________|
Run Code Online (Sandbox Code Playgroud)
然后我关闭文件描述符 1:
close(1);
Run Code Online (Sandbox Code Playgroud)
文件描述符 1 将(指向)转换为内核的Open Files Table 中的 stdout FILE 结构。
使用上面的代码,文件描述符 1 从进程表中删除,变成:
_process1_
| |
| 0 stdin |
| 2 stderr |
|__________|
Run Code Online (Sandbox Code Playgroud)
但是在内核中发生了什么?stdoutFILE 结构是否被解除分配?如果 stdout 是一个特殊文件(监视器)并且可能被其他进程使用,那怎么可能呢?FILE 结构只是普通文件(例如.txt)呢?如果其他进程正在使用这样的文件怎么办?
我有一个 bash 脚本来测试一些程序,其中一个程序返回,Segmentation fault所以我试图在我的脚本的头部添加一个陷阱:
trap "echo 'segfault occured!'" SIGSEGV
Run Code Online (Sandbox Code Playgroud)
然而这并没有起到任何作用。我用了
echo $?
Run Code Online (Sandbox Code Playgroud)
就在产生段错误的程序之后,我得到139作为输出。如何为该特定错误代码添加陷阱?
我有一个新驱动器,我可以cp在驱动器上简单地复制文件。但是,出于某种奇怪的原因,我Permission denied使用了 ffmpeg。
除非我遗漏了什么,否则权限似乎很好
> ll /media/manos/6TB/
drwxrwxrwx 13 manos 4096 Apr 16 00:56 ./
drwxr-x---+ 6 manos 4096 Apr 16 00:49 ..
-rwxrwxrwx 1 manos 250900209 Apr 15 17:28 test.mp4*
..
Run Code Online (Sandbox Code Playgroud)
但是 ffmpeg 一直在抱怨
> ffmpeg -i test.mp4 test.mov
ffmpeg version n4.1.4 Copyright (c) 2000-2019 the FFmpeg developers
built with gcc 7 (Ubuntu 7.4.0-1ubuntu1~18.04.1)
configuration: --prefix= --prefix=/usr --disable-debug --disable-doc --disable-static --enable-avisynth --enable-cuda --enable-cuvid --enable-libdrm --enable-ffplay --enable-gnutls --enable-gpl --enable-libass --enable-libfdk-aac --enable-libfontconfig --enable-libfreetype --enable-libmp3lame --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libopus …Run Code Online (Sandbox Code Playgroud) 可能的重复:
不同进程中的相同 fd 如何指向同一个文件?
我很难掌握File Descriptor Table和Open File Table这两个概念。
打开文件表是内核中的一个表,其中包含系统中所有打开的文件,我理解这一点。但是我不明白与文件描述符的联系。

如果文件描述符确实是文件的索引,那么为什么两个不同进程中的文件描述符 4 指向两个完全不同的文件(即文件 A 和文件 B)?我们如何在打开文件表中有两次文件 A ?每个文件不应该只呈现一次吗?
最近我在一个powerpoint演示文稿中发现了这一点:
当一个程序被编译和链接时,链接器会在程序中插入一些额外的代码。正是这段代码调用主函数的方式与用户调用“下层函数”的方式大致相同。
额外的代码有两个功能:
- 确保 C 程序在正确的环境中运行
- 成功终止后的清理
在此之前,我认为清理是内核的工作。什么是正确的故事?
open-files ×3
kernel ×2
linux ×2
bash ×1
exit ×1
external-hdd ×1
ffmpeg ×1
fstab ×1
permissions ×1
process ×1
signals ×1
snap ×1
table ×1
trap ×1