我发现了很多关于如何仅删除符号链接或根据其内容删除符号链接的问题,但没有人问过我该如何做。
以下面的例子为例
file-l -> ../file
file-l2 -> ../file
我想一次性删除file
、file-l
和file-l2
,而不需要知道其他文件的位置,最好通过指定file
参数来实现。(假设我在文件系统的随机位置有 100 多个指向同一文件的链接)。首先,我更喜欢使用 shell 脚本或内置程序,但外部程序也可以。
在unlink
和rm
未能提供所需的功能之后,我最初的想法是使用inodes
或stat
或某样东西,但是......
$ stat test
File: ‘test’
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: 811h/2065d Inode: 27001032 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1000/ braden) Gid: ( 1000/ braden)
Access: 2015-08-30 21:30:35.578786598 -0600
Modify: 2015-08-30 21:30:35.578786598 -0600
Change: 2015-08-30 21:30:35.578786598 -0600
Birth: -
$ stat test-l
File: ‘test-l’ -> ‘test’
Size: 4 Blocks: 0 IO Block: 4096 symbolic link
Device: 811h/2065d Inode: 27001033 Links: 1
Access: (0777/lrwxrwxrwx) Uid: ( 1000/ braden) Gid: ( 1000/ braden)
Access: 2015-08-30 21:30:42.074786598 -0600
Modify: 2015-08-30 21:30:41.426786598 -0600
Change: 2015-08-30 21:30:41.426786598 -0600
Birth: -
符号链接不仅具有唯一的 inode(这是给定的),而且除了文件名之外似乎没有任何信息可以用来得出结论“是的,这是我想要的文件的符号链接”。但是,如果我使用文件名,那么我必须处理正则表达式地狱。这是我个人想避免的事情,因为在实践中,文件名包含空格、元字符(?![]{}.,
)和 unicode 字符等字符。
我还想避免使用 awk、perl、利用 bash 4.2.XX 中的错误/设计缺陷的疯狂黑客,以及其他可能无法在全新安装的 Arch Linux 或 CentOS 等上正常工作(甚至根本无法正常工作)的奇怪东西。我基本上应该能够在缺少 awk、sed、perl、ruby 和 python 且运行 bash-4.1 作为其 shell 的系统上开箱即用地运行上述命令/脚本。
如果那不可能,那么我至少更希望脚本/命令的使用/无处不在,例如vi
,,,等等cat
。ls
我的最低要求是解决方案:
- 可以删除文件及其所有符号链接,只需将原始文件作为参数即可
- 无需知道上述符号链接的名称或位置即可执行此操作
- 可以在不同名称和不同位置的符号链接上执行此操作
- 在全新、最小安装的 Arch Linux(或类似的最小系统)中运行
- 不是代码高尔夫
- 正则表达式合理且易于理解
这是我尝试设计自己的剧本的方式,所以我认为这是合理的。但我还是希望它不会太苛刻。
谢谢。
编辑:我觉得我有义务展示我的作品。光是要求一份脚本就让我觉得自己是个混蛋。所以,这就是我所拥有的:
get_lnk(){
gl_file="$1"
gl_orig_a=( $(ls -l "$gl_file") )
gl_orig="${gl_orig_a[-1]}"
}
for i in *; do
get_lnk "$i"
echo "file: $gl_file"
echo "links to: $gl_orig"
echo
done
# output:
file: file-l
links to: ../file
file: file-l2
links to: ../file
这将打印符号链接的名称及其指向的文件的名称。这实际上与我想要做的相反,但相当有用(当所有链接都在同一位置时)。
答案1
假设您有一个名为file1
in 的文件~/tmp
,并且假设您想要递归删除指向file1
in 的所有符号链接~/tmp
;
使用find
:
find ~/tmp -lname ~/tmp/file1 -exec rm {} +
~/tmp
:指定要搜索的目录层次结构的路径;-lname
: 仅搜索链接到的符号链接~/tmp/file1
;-exec rm {} +
:删除所有结果;
测试目录层次结构的示例输出:
user@debian ~/tmp % tree
.
├── 1
│ ├── 2
│ │ ├── 3
│ │ │ ├── link3-1 -> /home/user/tmp/file1
│ │ │ └── link3-2 -> /home/user/tmp/file2
│ │ ├── link2-1 -> /home/user/tmp/file1
│ │ └── link2-2 -> /home/user/tmp/file2
│ ├── link1-1 -> /home/user/tmp/file1
│ └── link1-2 -> /home/user/tmp/file2
├── file1
└── file2
3 directories, 8 files
user@debian ~/tmp % find . -lname ~/tmp/file1 -exec rm {} +
user@debian ~/tmp % tree
.
├── 1
│ ├── 2
│ │ ├── 3
│ │ │ └── link3-2 -> /home/user/tmp/file2
│ │ └── link2-2 -> /home/user/tmp/file2
│ └── link1-2 -> /home/user/tmp/file2
├── file1
└── file2
3 directories, 5 files