用文件替换符号链接

Mar*_*uth 40 linux bash

有没有一种简单的方法可以用它们链接到的文件替换所有符号链接?

Red*_*edX 23

如果我理解正确,命令的-L标志cp应该完全符合您的要求。

只需复制所有符号链接,它将用它们指向的文件替换它们。

cp -L files tmp/ && rm files && mv tmp/files .

  • 谢谢 - 几乎是我需要的:我必须做类似的事情:`cp -L files tmp/ && rm files && cp tmp/files .`如果你澄清,你可能会帮助更多人...... (8认同)

use*_*686 19

对于“简单”的一些定义:

#!/bin/sh
set -e
for link; do
    test -h "$link" || continue

    dir=$(dirname "$link")
    reltarget=$(readlink "$link")
    case $reltarget in
        /*) abstarget=$reltarget;;
        *)  abstarget=$dir/$reltarget;;
    esac

    rm -fv "$link"
    cp -afv "$abstarget" "$link" || {
        # on failure, restore the symlink
        rm -rfv "$link"
        ln -sfv "$reltarget" "$link"
    }
done
Run Code Online (Sandbox Code Playgroud)

使用链接名称作为参数运行此脚本,例如通过 find . -type l -exec /path/tos/script {} +

  • 感谢您的编辑,匿名,但脚本 _does_ 处理带空格的文件名就好了,通过在所有必要的地方引用变量。将 `"$var"` 更改为 `"${var}"` 是 sh/bash 中的一个 noop。我删除了一个 bashism (`[[`),其余的与 POSIX sh 兼容。 (2认同)

Ste*_*eve 18

仅使用 tar 将数据复制到新目录可能更容易。

-H      (c and r mode only) Symbolic links named on the command line will
        be followed; the target of the link will be archived, not the
        link itself.
Run Code Online (Sandbox Code Playgroud)

你可以使用这样的东西

tar -hcf - sourcedir | tar -xf - -C newdir

tar --help:
-H, --format=FORMAT        create archive of the given format
-h, --dereference          follow symlinks; archive and dump the files they point to
Run Code Online (Sandbox Code Playgroud)


Jam*_*ell 6

“容易”很可能是你的一个功能。

我可能会编写一个脚本,使用“find”命令行实用程序来查找符号链接的文件,然后调用 rm 和 cp 来删除和替换文件。在移动符号链接之前,您可能还可以让 find 调用的操作检查是否还有足够的可用空间。

另一种解决方案可能是通过隐藏符号链接的东西(如 samba)挂载有问题的文件系统,然后从中复制所有内容。但在许多情况下,类似的事情会引入其他问题。

对您的问题更直接的回答可能是“是”。

编辑:根据对更具体信息的请求。根据find手册页,此命令将列出 2 个目录中的所有符号链接文件,从 /:

find / -maxdepth 2 -type l -print
Run Code Online (Sandbox Code Playgroud)

这是在这里找到的

要让 find 在找到它时执行某些操作:

find / -maxdepth 2 -type l -exec ./ReplaceSymLink.sh {} \;
Run Code Online (Sandbox Code Playgroud)

我相信这会调用我刚刚编写的一些脚本,并传入您刚刚找到的文件名。或者,您可以将 find 输出捕获到文件(使用“find [blah] > symlinks.data”等),然后将该文件传递给您编写的脚本以优雅地处理原始文件的复制。

  • 语法是`-exec ./ReplaceSymLink.sh {} \;` (2认同)

Die*_*ego 6

find ./ -type l -exec sh -c 'for i in "$@"; do cp --preserve --remove-destination "$(readlink -f "$i")" "$i"; done' sh {} +
Run Code Online (Sandbox Code Playgroud)

基于MastroGeppetto 的https://superuser.com/a/1301199/499386并由 @tom 进行编辑