Linux:查找给定“原始”文件的所有符号链接?(反向'阅读链接')
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4532241/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Linux: Find all symlinks of a given 'original' file? (reverse 'readlink')
提问by sdaau
Consider the following command line snippet:
考虑以下命令行片段:
$ cd /tmp/
$ mkdir dirA
$ mkdir dirB
$ echo "the contents of the 'original' file" > orig.file
$ ls -la orig.file
-rw-r--r-- 1 $USER $USER 36 2010-12-26 00:57 orig.file
# create symlinks in dirA and dirB that point to /tmp/orig.file:
$ ln -s $(pwd)/orig.file $(pwd)/dirA/
$ ln -s $(pwd)/orig.file $(pwd)/dirB/lorig.file
$ ls -la dirA/ dirB/
dirA/:
total 44
drwxr-xr-x 2 $USER $USER 4096 2010-12-26 00:57 .
drwxrwxrwt 20 root root 36864 2010-12-26 00:57 ..
lrwxrwxrwx 1 $USER $USER 14 2010-12-26 00:57 orig.file -> /tmp/orig.file
dirB/:
total 44
drwxr-xr-x 2 $USER $USER 4096 2010-12-26 00:58 .
drwxrwxrwt 20 root root 36864 2010-12-26 00:57 ..
lrwxrwxrwx 1 $USER $USER 14 2010-12-26 00:58 lorig.file -> /tmp/orig.file
At this point, I can use readlink
to see what is the 'original' (well, I guess the usual term here is either 'target' or 'source', but those in my mind can be opposite concepts as well, so I'll just call it 'original') file of the symlinks, i.e.
在这一点上,我可以readlink
用来看看什么是“原始”(好吧,我猜这里的常用术语是“目标”或“源”,但我脑海中的那些也可能是相反的概念,所以我会只需将其称为“原始”)符号链接文件,即
$ readlink -f dirA/orig.file
/tmp/orig.file
$ readlink -f dirB/lorig.file
/tmp/orig.file
... However, what I'd like to know is - is there a command I could run on the 'original' file, and find all the symlinks that point to it? In other words, something like (pseudo):
...但是,我想知道的是 - 有没有我可以在“原始”文件上运行的命令,并找到指向它的所有符号链接?换句话说,类似于(伪):
$ getsymlinks /tmp/orig.file
/tmp/dirA/orig.file
/tmp/dirB/lorig.file
Thanks in advance for any comments,
提前感谢您的任何评论,
Cheers!
干杯!
采纳答案by paxdiablo
I've not seen a command for this and it's not an easy task, since the target file contains zero information on what source files point to it.
我还没有看到用于此的命令,这不是一项容易的任务,因为目标文件包含有关哪些源文件指向它的零信息。
This is similar to "hard" links but at least those are always on the same file system so you can do a find -inode
to list them. Soft links are more problematic since they can cross file systems.
这类似于“硬”链接,但至少它们始终位于同一文件系统上,因此您可以find -inode
列出它们。软链接问题更多,因为它们可以跨文件系统。
I think what you're going to have to do is basically perform an ls -al
on every file in your entire hierarchy and use grep
to search for -> /path/to/target/file
.
我认为您要做的基本上是ls -al
对整个层次结构中的每个文件执行 an并用于grep
搜索-> /path/to/target/file
.
For example, here's one I ran on my system (formatted for readability - those last two lines are actually on oneline in the real output):
例如,这里是我的系统上的一个我跑(格式化的可读性-最后两行实际上是对一个在现实输出线):
pax$ find / -exec ls -ald {} ';' 2>/dev/null | grep '\-> /usr/share/applications'
lrwxrwxrwx 1 pax pax 23 2010-06-12 14:56 /home/pax/applications_usr_share
-> /usr/share/applications
回答by jilles
Symlinks do not track what is pointing to a given destination, so you cannot do better than checking each symlink to see if it points to the desired destination, such as
符号链接不会跟踪指向给定目的地的内容,因此您不能比检查每个符号链接以查看它是否指向所需的目的地更好,例如
for i in *; do
if [ -L "$i" ] && [ "$i" -ef /tmp/orig.file ]; then
printf "Found: %s\n" "$i"
fi
done
回答by Gordon Davisson
Here's what I came up with. I'm doing this on OS X, which doesn't have readlink -f
, so I had to use a helper function to replace it. If you have it a proper readlink -f
you can use that instead. Also, the use of while ... done < <(find ...)
is not strictly needed in this case, a simple find ... | while ... done
would work; but if you ever wanted to do something like set a variable inside the loop (like a count of matching files), the pipe version would fail because the while
loop would run in a subshell. Finally, note that I use find ... -type l
so the loop only executes on symlinks, not other types of files.
这是我想出的。我在 OS X 上这样做,它没有readlink -f
,所以我不得不使用辅助函数来替换它。如果你有一个合适的,readlink -f
你可以用它来代替。此外,while ... done < <(find ...)
在这种情况下并不严格需要使用,简单的find ... | while ... done
就可以了;但是如果你想在循环中设置一个变量(比如匹配文件的计数),管道版本就会失败,因为while
循环将在子shell中运行。最后,请注意我使用find ... -type l
so 循环仅在符号链接上执行,而不是其他类型的文件。
# Helper function 'cause my system doesn't have readlink -f
readlink-f() {
orig_dir="$(pwd)"
f=""
while [[ -L "$f" ]]; do
cd "$(dirname "$f")"
f="$(readlink "$(basename "$f")")"
done
cd "$(dirname "$f")"
printf "%s\n" "$(pwd)/$(basename "$f")"
cd "$orig_dir"
}
target_file="$(readlink-f "$target_file")" # make sure target is normalized
while IFS= read -d '' linkfile; do
if [[ "$(readlink-f "$linkfile")" == "$target_file" ]]; then
printf "%s\n" "$linkfile"
fi
done < <(find "$search_dir" -type l -print0)
回答by Paused until further notice.
Using GNU find
, this will find the files that are hard linked or symlinked to a file:
使用 GNU find
,这将找到硬链接或符号链接到文件的文件:
find -L /dir/to/start -samefile /tmp/orig.file
回答by Landis Reed
This may be too simplistic for what you want to do, but I find it useful. it does Not answer your question literally, as it's not 'run on the original file', but it accomplishes the task. But, a lot more HDD access. And, it only works for 'soft' linked files which is majority of user linked files.
这对于您想要做的事情来说可能过于简单,但我发现它很有用。它不会从字面上回答您的问题,因为它不是“在原始文件上运行”,但它完成了任务。但是,更多的硬盘访问。而且,它仅适用于“软”链接文件,这是大多数用户链接文件。
from the root of you data storage directory or users data directories, wherever symlinked
'files' to the orig.file
may reside, run the find command:
从您的数据存储目录或用户数据目录的根目录,无论symlinked
“文件”orig.file
可能驻留在何处,运行 find 命令:
# find -type l -ls |grep -i 'orig.file'
or
或者
# find /Starting/Search\ Path/ -type l -ls |grep -i '*orig*'
I would Normally use part of the name eg, '*orig*'
to start, because we know users will rename (prefix) a simply named file with a more descriptive one like " Jan report from London _ orig.file.2015.01.21 " or something.
我通常会使用名称的一部分,例如,'*orig*'
开始,因为我们知道用户会使用更具描述性的文件重命名(前缀)一个简单命名的文件,例如“来自伦敦的 Jan 报告 _ orig.file.2015.01.21”或其他内容。
Note: I've Never gotten the -samefile option to work for me.
注意:我从来没有让 -samefile 选项对我有用。
clean, simple, easy to remember
干净、简单、容易记住
hope this helps Someone. Landis.
希望这有助于某人。兰迪斯。
回答by Jer
Inspired by Gordon Davisson's comment. This is similar to another answer, but I got the desired results using exec. I needed something that could find symbolic links without knowing where the original file was located.
灵感来自戈登戴维森的评论。这类似于另一个答案,但我使用 exec 得到了想要的结果。我需要一些可以在不知道原始文件所在位置的情况下找到符号链接的东西。
find / -type l -exec ls -al {} \; | grep -i "all_or_part_of_original_name"