Linux:查找给定“原始”文件的所有符号链接? (反向“readlink”)
考虑下面的命令行片段:
$ 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
在这一点上,我可以用readlink
来看看“原始”是什么( readlink
,我猜这里通常的术语是'目标'或'源头',但是脑海中的那些也可能是相反的概念,我们只是把它叫做'original')文件的符号链接,即
$ readlink -f dirA/orig.file /tmp/orig.file $ readlink -f dirB/lorig.file /tmp/orig.file
…但是,我想知道的是 – 是否有一个命令,我可以在“原始”文件上运行,并find所有符号链接指向它? 换句话说,像(伪)这样的东西:
$ getsymlinks /tmp/orig.file /tmp/dirA/orig.file /tmp/dirB/lorig.file
在此先感谢您的任何意见,
干杯!
我还没有看到一个这样的命令,这不是一件容易的事情,因为目标文件包含零信息源文件指向它。
这与“硬”链接类似,但至less它们总是在同一个文件系统上,所以你可以做一个find -inode
来列出它们。 由于软链接可以跨文件系统,因此软链接更成问题。
我认为你将不得不做的是基本上对整个层次结构中的每个文件执行ls -al
,并使用grep
来search-> /path/to/target/file
。
例如,下面是我在我的系统上运行的一个(格式化为可读性 – 实际输出中最后两行实际上在一行上):
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
使用GNU find
,这将find硬链接或符号链接到一个文件的文件:
find -L /dir/to/start -samefile /tmp/orig.file
符号链接不会跟踪指向给定目的地的内容,因此您无法比检查每个符号链接来查看它是否指向所需的目标,例如
for i in *; do if [ -L "$i" ] && [ "$i" -ef /tmp/orig.file ]; then printf "Found: %s\n" "$i" fi done
这是我想出来的。 我在OS X上做这个,它没有readlink -f
,所以我不得不使用一个辅助函数来replace它。 如果你有一个正确的readlink -f
你可以使用它。 另外,在这种情况下,使用while ... done < <(find ...)
并不是严格需要的,一个简单的find ... | while ... done
find ... | while ... done
将工作; 但是如果你曾经想要在循环中设置一个variables(比如匹配文件的数量),pipe道版本将会失败,因为while
循环会在子shell中运行。 最后,请注意,我使用find ... -type l
因此循环仅在符号链接上执行,而不是其他types的文件。
# Helper function 'cause my system doesn't have readlink -f readlink-f() { orig_dir="$(pwd)" f="$1" 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)
这可能对你想做的事情来说太简单了,但是我觉得它很有用。 它不会从字面上回答你的问题,因为它不是'在原始文件上运行',而是完成了任务。 但是,更多的硬盘访问。 而且,它只适用于大多数用户链接文件的“软”链接文件。
从数据存储目录或用户数据目录的根目录中,无论将“文件”链接到orig.file
任何位置, orig.file
可以运行find命令:
# find -type l -ls |grep -i 'orig.file'
要么
# find /Starting/Search\ Path/ -type l -ls |grep -i '*orig*'
我会通常使用名称的一部分,例如'*orig*'
来启动,因为我们知道用户会重命名(前缀)一个更具描述性的文件,如“Jan report from London _ orig.file.2015.01.21 “ 或者其他的东西。
注意:我从来没有得到-samefile选项为我工作。
干净,简单,易于记忆
希望这有助于某人。 兰迪斯。