簡體   English   中英

如何檢查Linux符號鏈接是否正在使用? (刪除未使用的符號鏈接)

[英]how to check if Linux symlink is in use? (removing unused symlink)

只有在使用原始文件時,熱熔器才能顯示給您。

如果SYMLINK在使用中調用原始文件,則熱熔器不顯示您。 這就是問題所在。 您不知道symlink是否未使用且可以刪除。

我已經啟動了兩個進程(24261打開原始文件,24262打開符號鏈接):

root@server DEV # ls -l /lib64/libgcc_s-4.4.7-20120601.so.1
-rwxr-xr-x 1 root root 93320 Sep  1  2014 /lib64/libgcc_s-4.4.7-20120601.so.1
root@server DEV # ls -l /usr/lib/gcc/x86_64-redhat-linux/4.4.4/libgcc_s.so
lrwxrwxrwx. 1 root root 20 Oct 19  2015 /usr/lib/gcc/x86_64-redhat-linux/4.4.4/libgcc_s.so -> /lib64/libgcc_s.so.1
root@server DEV #
root@server DEV # tail -f /lib64/libgcc_s.so.1 &
[1] 24261
root@server DEV #
root@server DEV # cd /usr/lib/gcc/x86_64-redhat-linux/4.4.4
root@server DEV # tail -f libgcc_s.so &
[2] 24262
root@server DEV #
root@server DEV # ps -ef | grep tail
root     24261  3265  0 13:39 pts/1    00:00:00 tail -f /lib64/libgcc_s.so.1
root     24262  3265  0 13:39 pts/1    00:00:00 tail -f libgcc_s.so
root     24492  3265  0 13:40 pts/1    00:00:00 grep tail
root@server DEV #

在這兩種情況下,fuser都會告訴我們正在使用符號鏈接和原始文件(每個命令有兩個進程):

root@server DEV # fuser /lib64/libgcc_s.so.1
/lib64/libgcc_s.so.1: 24261 24262
root@server DEV # fuser /usr/lib/gcc/x86_64-redhat-linux/4.4.4/libgcc_s.so
/usr/lib/gcc/x86_64-redhat-linux/4.4.4/libgcc_s.so: 24261 24262
root@server DEV #

但是我們知道第一個進程沒有使用符號鏈接。 它甚至可以被移除,不會影響第一個過程。

假設我沒有使用包,我想刪除'gcc'包。

原始文件來自'libgcc'包。

root@server DEV # rpm -qf /lib64/libgcc_s.so.1
libgcc-4.4.7-11.el6.x86_64

Symlink來自'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_s.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中看到完整的符號鏈接路徑嗎?

符號鏈接不是通常的文件:它們不能像常規文件或目錄一樣使用open() 符號鏈接實際上只是一個常量字符串 ,在路徑解析期間會自動在內部解釋。

因為符號鏈接不會像fuser這樣的實用程序被“使用”。 當你為符號鏈接調用fuser時 ,它實際上顯示了鏈接指向的文件的信息。

如果“在使用中”是指“一個或多個程序正在使用鏈接作為文件的路徑名”,那么就無法分辨。 它本來可以在昨天使用,它可能會在明天使用。 Unix的設計使得除非您專門使用為特定目的設計的工具,否則符號鏈接看起來就像它指向的文件。 fuserlsof這樣的程序只是直接通過鏈接,甚至沒有告訴你它是一個鏈接。

如果“使用中”是指“指向有效文件”,那么有辦法告訴。 最簡單的是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

不幸的是,Linux內核旨在在啟動階段從符號鏈接中分配原始文件。 因此,當進程運行時,無法檢查文件是直接調用還是通過符號鏈接調用。

您所能做的就是檢查當前工作目錄是什么ls -l /proc/<process_id>/cwd ,命令行參數strings /proc/<process_id>/cmdline ,用戶啟動了什么進程ps -ef | grep <process_id> ps -ef | grep <process_id>然后你可以檢查用戶啟動腳本和$PATHldd可以顯示從特定庫調用哪些庫。 如果你想重新啟動進程以查看symlink是否被調用,那么strace就是你的朋友。

這個問題的前提(用fuser / lsof識別未使用的包)從根本上是有缺陷的:

並非您的系統需要正常工作的每個文件都會在任何隨機時間由打開的文件描述符引用。

例如,如果刪除/bin/systemctl (因為/sbin/shutdown類的符號鏈接),你會遇到錯誤的時間,但是lsof沒有使用它。

很容易想出更多的例子,例如我的系統上的/bin/grep 它在shell腳本中被廣泛使用,但我沒有碰巧有任何長期運行的實例。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM