如何在我当前的 bash 会话中列出打开的文件描述符(以及它们引用的文件)

blu*_*ast 50 linux bash file-descriptors open-files

我正在交互式 bash 会话中运行。我已经使用 exec 创建了一些文件描述符,我想列出我的 bash 会话的当前状态。

有没有办法列出当前打开的文件描述符?

ImH*_*ere 61

是的,这将列出所有打开的文件描述符:

$ ls -la /proc/$$/fd
total 0
dr-x------ 2 isaac isaac  0 Dec 28 00:56 .
dr-xr-xr-x 9 isaac isaac  0 Dec 28 00:56 ..
lrwx------ 1 isaac isaac 64 Dec 28 00:56 0 -> /dev/pts/6
lrwx------ 1 isaac isaac 64 Dec 28 00:56 1 -> /dev/pts/6
lrwx------ 1 isaac isaac 64 Dec 28 00:56 2 -> /dev/pts/6
lrwx------ 1 isaac isaac 64 Dec 28 00:56 255 -> /dev/pts/6
l-wx------ 1 isaac isaac 64 Dec 28 00:56 4 -> /home/isaac/testfile.txt
Run Code Online (Sandbox Code Playgroud)

当然,和往常一样:0 是标准输入,1 是标准输出,2 是标准错误。
在这种情况下,第四个是打开的文件(写入)。

  • 那只是列出当前进程,而不是它的子进程或父进程。 (2认同)
  • 什么是 /proc/$$ ?特别是“$$”是如何工作的? (2认同)
  • @JZ.`$$` 将给出当前运行的 shell 的进程 ID。试试 `echo $$` 和 `ps` 并比较它们的输出。类似的问题[这里](https://unix.stackexchange.com/questions/291570/what-is-in-bash)。 (2认同)

hee*_*ayl 9

假设您要列出附加到任何终端的文件描述符,您可以使用lsof/fuser或类似的:

$ lsof -p $$ 2>/dev/null | awk '$NF ~ /\/pts\//'
bash    32406 foobar    0u   CHR 136,31      0t0      34 /dev/pts/31
bash    32406 foobar    1u   CHR 136,31      0t0      34 /dev/pts/31
bash    32406 foobar    2u   CHR 136,31      0t0      34 /dev/pts/31
bash    32406 foobar    3u   CHR 136,31      0t0      34 /dev/pts/31
bash    32406 foobar  255u   CHR 136,31      0t0      34 /dev/pts/31
Run Code Online (Sandbox Code Playgroud)

这些工具基本上是 parse /proc,因此您也可以访问,/proc/$$/fd/例如:

ls /proc/$$/fd/*
Run Code Online (Sandbox Code Playgroud)

  • `\/pts\/` 的选择拒绝像 `exec 4>testfile.txt` 这样的打开文件 (4认同)

Ant*_*gan 5

使用该lsof实用程序打印当前 shell 进程(由-p $$( -a) 标识的进程的所有文件描述符,其中文件描述符是数字 ( -d 0-256):

\n
$ lsof -p $$ -a -d 0-256\nCOMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME\nbash    16883  ant    0u   CHR 136,15      0t0   18 /dev/pts/15\nbash    16883  ant    1u   CHR 136,15      0t0   18 /dev/pts/15\nbash    16883  ant    2u   CHR 136,15      0t0   18 /dev/pts/15\nbash    16883  ant  255u   CHR 136,15      0t0   18 /dev/pts/15\n
Run Code Online (Sandbox Code Playgroud)\n

通过管道输入 Awk 以仅打印文件描述符及其相应的文件名:

\n
$ lsof -p $$ -a -d 0-256  | awk \'{ printf("%4s:\\t%s\\n", $4, $NF) }\'\n  FD:   NAME\n  0u:   /dev/pts/15\n  1u:   /dev/pts/15\n  2u:   /dev/pts/15\n255u:   /dev/pts/15\n
Run Code Online (Sandbox Code Playgroud)\n

注意:lsof打印文件描述符时,会附加以下代码来指示文件访问模式:

\n
    \n
  • r\xe2\x80\x93 读取权限
  • \n
  • w\xe2\x80\x93 写入权限
  • \n
  • u\xe2\x80\x93 读写权限
  • \n
\n