Contents

在当前bash会话中列出打开的文件描述符

1. 简介

在使用 bash shell 时,我们的 shell 进程可能会因为多种原因而出现各种打开的文件。这些打开的文件每个都有一个相应的文件描述符整数,Linux 的用户空间在通过系统调用或库调用与内核空间通信时使用该整数来标识特定文件。

在本教程中,我们将讨论如何从 bash 会话本身中查看该 bash 会话的打开文件描述符。

2. 使用ls

我们可以使用ls 命令列出给定目录中的目录和文件。此外,内核通过** proc伪文件系统导出有关 Linux 系统上所有正在运行的进程的信息**。

默认情况下,这个文件系统几乎总是挂载在*/proc上。我们可以利用/proc下导出的信息并将其与ls*命令结合起来,列出进程的打开文件描述符。

在*/proc伪文件系统中,我们可以在/proc/pid/fd/*下找到打开的文件描述符,其中 pid 是给定进程的 PID。因此,我们必须确定进程的进程标识号 (PID) 才能查看其打开的文件描述符。*要获取 bash 会话进程的 PID,我们使用$$*表达式。*当我们在 bash 命令中使用$$*表达式时,它会扩展为当前 bash 会话的 PID。

因此,我们可以使用ls命令和*$$*表达式来显示当前 bash 会话的文件描述符以及它们引用的文件

$ ls -la /proc/$$/fd/
total 0
dr-x------ 2 user user  0 Apr  7 17:14 .
dr-xr-xr-x 9 user user  0 Apr  7 17:14 ..
lrwx------ 1 user user 64 Apr  7 17:14 0 -> /dev/pts/50
lrwx------ 1 user user 64 Apr  7 17:14 1 -> /dev/pts/50
lrwx------ 1 user user 64 Apr  7 17:14 2 -> /dev/pts/50
lrwx------ 1 user user 64 Apr  7 17:14 255 -> /dev/pts/50
lr-x------ 1 user user 64 Apr  7 17:14 3 -> /tmp/testfile2
l-wx------ 1 user user 64 Apr  7 17:14 4 -> /tmp/testfile1

3. 使用lsof

lsof 命令列出有关系统上正在运行的进程的打开文件的信息。 当我们不带任何参数运行lsof时,它会显示系统上运行的每个进程的打开文件。这也将使lsof以“重复”模式运行,这将导致输出循环。但是,我们不必过多担心重复模式,因为以下命令会阻止这种情况。

我们可以告诉lsof列出 bash 会话进程的打开文件,方法是使用*-p*选项和我们与ls一起使用的$$ shell 表达式:

$ lsof  -p $$
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF  NODE NAME
bash    14928 user  cwd    DIR  252,1     4096  4060 /tmp
bash    14928 user  rtd    DIR  252,1     4096     2 /
bash    14928 user  txt    REG  252,1  1113504    32 /bin/bash
bash    14928 user  mem    REG  252,1    47568 26949 /lib/x86_64-linux-gnu/libnss_files-2.27.so
bash    14928 user  mem    REG  252,1    97176 26946 /lib/x86_64-linux-gnu/libnsl-2.27.so
bash    14928 user  mem    REG  252,1    47576 26951 /lib/x86_64-linux-gnu/libnss_nis-2.27.so
bash    14928 user  mem    REG  252,1    39744 26947 /lib/x86_64-linux-gnu/libnss_compat-2.27.so
bash    14928 user  mem    REG  252,1  1516558 30707 /usr/lib/locale/C.UTF-8/LC_COLLATE
bash    14928 user  mem    REG  252,1  2030928 26939 /lib/x86_64-linux-gnu/libc-2.27.so
bash    14928 user  mem    REG  252,1    14560 26942 /lib/x86_64-linux-gnu/libdl-2.27.so
bash    14928 user  mem    REG  252,1   170784  2104 /lib/x86_64-linux-gnu/libtinfo.so.5.9
bash    14928 user  mem    REG  252,1   179152 26935 /lib/x86_64-linux-gnu/ld-2.27.so
bash    14928 user  mem    REG  252,1   199772 30708 /usr/lib/locale/C.UTF-8/LC_CTYPE
bash    14928 user  mem    REG  252,1       50 30720 /usr/lib/locale/C.UTF-8/LC_NUMERIC
bash    14928 user  mem    REG  252,1     3360 30724 /usr/lib/locale/C.UTF-8/LC_TIME
bash    14928 user  mem    REG  252,1      270 30715 /usr/lib/locale/C.UTF-8/LC_MONETARY
bash    14928 user  mem    REG  252,1       48 30714 /usr/lib/locale/C.UTF-8/LC_MESSAGES/SYS_LC_MESSAGES
bash    14928 user  mem    REG  252,1       34 30722 /usr/lib/locale/C.UTF-8/LC_PAPER
bash    14928 user  mem    REG  252,1  1683056  4354 /usr/lib/locale/locale-archive
bash    14928 user  mem    REG  252,1       62 30718 /usr/lib/locale/C.UTF-8/LC_NAME
bash    14928 user  mem    REG  252,1      131 30705 /usr/lib/locale/C.UTF-8/LC_ADDRESS
bash    14928 user  mem    REG  252,1       47 30723 /usr/lib/locale/C.UTF-8/LC_TELEPHONE
bash    14928 user  mem    REG  252,1       23 30713 /usr/lib/locale/C.UTF-8/LC_MEASUREMENT
bash    14928 user  mem    REG  252,1    26376 27208 /usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache
bash    14928 user  mem    REG  252,1      252 30709 /usr/lib/locale/C.UTF-8/LC_IDENTIFICATION
bash    14928 user    0u   CHR 136,50      0t0    53 /dev/pts/50
bash    14928 user    1u   CHR 136,50      0t0    53 /dev/pts/50
bash    14928 user    2u   CHR 136,50      0t0    53 /dev/pts/50
bash    14928 user    3r   REG  252,1        5   150 /tmp/testfile2
bash    14928 user    4w   REG  252,1        0  2230 /tmp/testfile1
bash    14928 user  255u   CHR 136,50      0t0    53 /dev/pts/50

我们从输出中看到,前面的命令包含的打开文件比我们的文件描述符引用的要多。

为了解决这个问题,我们可以通过指定从 0 到 INT_MAX 的范围使lsof只显示数字文件描述符。

因此,我们在下一个示例中使用*-d选项来指定文件描述符的范围。同样,我们使用-p选项来指定 PID。然后我们将它与-a*选项结合起来,将这些选择“和”(或组合)在一起:

$ lsof -a -d 0-2147483647 -p $$
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
bash    14928 user    0u   CHR 136,50      0t0   53 /dev/pts/50
bash    14928 user    1u   CHR 136,50      0t0   53 /dev/pts/50
bash    14928 user    2u   CHR 136,50      0t0   53 /dev/pts/50
bash    14928 user    3r   REG  252,1        5  150 /tmp/testfile2
bash    14928 user    4w   REG  252,1        0 2230 /tmp/testfile1
bash    14928 user  255u   CHR 136,50      0t0   53 /dev/pts/50