如何检查Linux符号链接是否正在使用?(删除未使用的符号链接)

如何检查Linux符号链接是否正在使用?(删除未使用的符号链接),linux,kernel,ps,lsof,fuser,Linux,Kernel,Ps,Lsof,Fuser,fuser只能在原始文件正在使用时显示 fuser不会显示调用原始文件的符号链接是否正在使用。这就是问题所在。您不知道符号链接是否未使用,是否可以删除 我启动了两个进程(24261打开原始文件和24262打开符号链接): 在这两种情况下,fuser都会告知正在使用符号链接和原始文件(每个命令有两个进程): 但我们知道第一个过程中没有使用symlink。它甚至可以被移除,并且不会影响第一个过程 假设我想删除未使用的“gcc”包 原始文件来自“libgcc”包 root@server DEV # r

fuser只能在原始文件正在使用时显示

fuser不会显示调用原始文件的符号链接是否正在使用。这就是问题所在。您不知道符号链接是否未使用,是否可以删除

我启动了两个进程(24261打开原始文件和24262打开符号链接):

在这两种情况下,fuser都会告知正在使用符号链接和原始文件(每个命令有两个进程):

但我们知道第一个过程中没有使用symlink。它甚至可以被移除,并且不会影响第一个过程

假设我想删除未使用的“gcc”包

原始文件来自“libgcc”包

root@server DEV # rpm -qf /lib64/libgcc_s.so.1
libgcc-4.4.7-11.el6.x86_64
符号链接来自“gcc”软件包:

root@server DEV # rpm -qf /usr/lib/gcc/x86_64-redhat-linux/4.4.4/libgcc_s.so
gcc-4.4.7-11.el6.x86_64
如果我将删除只包含符号链接的“gcc”包,我将影响第二个进程!如何查看符号链接是否未使用

在我的例子中,“ps-ef”显示我使用了以下命令:

root     24262  3265  0 13:39 pts/1    00:00:00 tail -f libgcc_s.so
所以ps甚至不能告诉你使用了符号链接

有Linux大师吗

编辑: 存在检查cwd-当前工作目录的部分解决方案:

root@server DEV # ls -l /proc/24262/cwd
lrwxrwxrwx 1 root root 0 Jun 20 13:57 /proc/24262/cwd -> /usr/lib/gcc/x86_64-redhat-linux/4.4.4
root@server DEV #
因此,从这里可以看到路径“/usr/lib/gcc/x86_64-redhat-linux/4.4.4”,您可以从ps获取文件名

如果您执行以下操作,则此操作无效:

root@server DEV # cd /root
root@server DEV # cat script.sh
/usr/bin/tail -f /usr/lib/gcc/x86_64-redhat-linux/4.4.4/libgcc_s.so
root@server DEV #
root@server DEV # nohup ./script.sh &
[2] 26713
root@server DEV #
root@server DEV # ls -l /proc/26713/cwd
lrwxrwxrwx 1 root root 0 Jun 20 14:32 /proc/26713/cwd -> /root
它显示/root的cwd,但符号链接在脚本/程序中。因此,您需要检查/usr/lib/gcc/x86_64-redhat-linux/4.4.4/libgcc_.So的ps chill进程

root@server DEV # ps -ef | grep 26713
root     26713  3265  0 14:32 pts/1    00:00:00 /bin/sh ./script.sh
root     26714 26713  0 14:32 pts/1    00:00:00 /usr/bin/tail -f /usr/lib/gcc/x86_64-redhat-linux/4.4.4/libgcc_s.so
root     26780  3265  0 14:38 pts/1    00:00:00 grep 26713
root@server DEV #
当您想要自动删除包(如果包未被使用)时,这会非常混乱

如果有人能看到更简单的方法,那就太好了。此外,如果有人能够确认使用cwd和ps子进程进行符号链接使用检测的准确性

如果script.sh是二进制文件,会发生什么?我是否仍能在“ps”或cwd中看到完整的符号链接路径?

如果“正在使用”是指“一个或多个程序正在使用链接作为文件的路径名”,则无法判断。昨天可能用过,明天也可能用过。Unix的设计目的是,除非您专门使用为特定目的而设计的工具,否则符号链接看起来就像它指向的文件。像
fuser
lsof
这样的程序将直接通过链接,甚至不会告诉您这是一个链接

如果“正在使用”的意思是“指向有效文件”,那么有几种方法可以判断。最简单的是
ls-L

$ ls -l foo
/bin/ls: cannot access foo: No such file or directory
$ ls -l g
lrwxrwxrwx 1 hymie users 3 2016-06-20 10:09 g -> foo
$ ls -lL g
/bin/ls: cannot access g: No such file or directory
符号链接不是常见的文件:它们不能像普通文件或目录那样用
open()
打开。符号链接实际上只是一个常量字符串,在路径解析过程中会自动在内部进行解释


正因为如此,在像
fuser
这样的实用程序中,符号链接并没有被“使用”。当您为symlink调用fuser时,它实际上会显示链接指向的文件的信息。

不幸的是,Linux内核设计用于在启动阶段从symlink分配原始文件。因此,当进程运行时,无法检查文件是直接调用还是通过符号链接调用


您所能做的就是检查当前工作目录是什么,命令行参数是什么,是什么用户启动了进程,然后您可以检查用户启动脚本和
$PATH
ldd
可以显示从特定库调用的库。如果要重新启动进程以查看是否调用了symlink,则
strace
是您的朋友。

此问题的前提(使用
fuser
/
lsof
识别未使用的包)存在根本性缺陷:

并非系统需要正常工作的每个文件都会在任意时间被打开的文件描述符引用

例如,如果您删除了
/bin/systemctl
(因为
/sbin/shutdown
之类的东西都是指向它的符号链接),那么您的日子会不好过,但lsof在使用它时不会显示任何内容


在我的系统上很容易找到更多的例子,比如
/bin/grep
。它在shell脚本中随处可见,但我没有任何长时间运行的实例。

为什么需要删除未使用的符号链接?我需要删除未使用的编译器(例如gcc)。这是出于安全目的。“未使用的编译器”和符号链接之间的关系是什么?它们在同一个包中。例如:
root@serverDEV#rpm-ql gcc | grep-e'/usr/bin/gcc'-e'/usr/lib/gcc/x86_64-redhat-linux/4.4.4/libgcc_.so'/usr/bin/gcc/usr/lib/gcc/x86_64-redhat-linux/4.4/libgcc_.s。所以现在我很困惑。您担心,如果您删除了gcc包,那么没有人能够使用它?这就是Unix/Linux无法轻松告诉您symlink的问题,如果它现在正在使用。如果流程是昨天运行的,或者是短暂的,等等,那么有一个解决方案“auditd”工具。
root@server DEV # ps -ef | grep 26713
root     26713  3265  0 14:32 pts/1    00:00:00 /bin/sh ./script.sh
root     26714 26713  0 14:32 pts/1    00:00:00 /usr/bin/tail -f /usr/lib/gcc/x86_64-redhat-linux/4.4.4/libgcc_s.so
root     26780  3265  0 14:38 pts/1    00:00:00 grep 26713
root@server DEV #
$ ls -l foo
/bin/ls: cannot access foo: No such file or directory
$ ls -l g
lrwxrwxrwx 1 hymie users 3 2016-06-20 10:09 g -> foo
$ ls -lL g
/bin/ls: cannot access g: No such file or directory